diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml index 082333f2fc..3e1411d47e 100644 --- a/.github/workflows/black.yml +++ b/.github/workflows/black.yml @@ -10,7 +10,7 @@ on: pull_request: branches: [master, dev] paths: - - "**/*.py" + - "**.py" schedule: # run CI every day even if no PRs/merges occur - cron: '0 12 * * *' @@ -42,7 +42,7 @@ jobs: cp pyproject.toml .github/linters - name: Black - uses: super-linter/super-linter/slim@v4.9.2 + uses: super-linter/super-linter/slim@v6.6.0 if: always() env: # run linter on everything to catch preexisting problems diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index c49f9c09c5..ebf16598b4 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -45,7 +45,7 @@ jobs: echo "::add-matcher::.github/workflows/matchers/yamllint.json" - name: Lint everything else - uses: super-linter/super-linter/slim@v6.1.1 + uses: super-linter/super-linter/slim@v6.6.0 if: always() env: # run linter on everything to catch preexisting problems @@ -57,6 +57,7 @@ jobs: VALIDATE_PYTHON_PYLINT: false VALIDATE_PYTHON_BLACK: false VALIDATE_PYTHON_ISORT: false + VALIDATE_PYTHON_RUFF: false VALIDATE_JSON: false VALIDATE_JAVASCRIPT_ES: false VALIDATE_JAVASCRIPT_STANDARD: false diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index 6a3ea99ba6..9b6d1869b6 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -43,7 +43,7 @@ jobs: echo "::add-matcher::.github/workflows/matchers/pylint.json" - name: Pylint - uses: super-linter/super-linter/slim@v6.1.1 + uses: super-linter/super-linter/slim@v6.6.0 if: always() env: # Run linters only on new files for pylint to speed up the CI diff --git a/setup.py b/setup.py index a669b82a30..981bd7c0b7 100644 --- a/setup.py +++ b/setup.py @@ -24,8 +24,8 @@ ], extras_require={ "lint": [ - "black==22.3.0", - "pylint==3.0.3", + "black==24.4.2", + "pylint==3.2.2", ], "test": [ "pytest", diff --git a/slither/__init__.py b/slither/__init__.py index dd9b8a1a22..8d6b166daa 100644 --- a/slither/__init__.py +++ b/slither/__init__.py @@ -1,4 +1,7 @@ """ .. include:: ../README.md """ + from .slither import Slither + +__all__ = ["Slither"] diff --git a/slither/__main__.py b/slither/__main__.py index 886d392c0d..972fd10fcf 100644 --- a/slither/__main__.py +++ b/slither/__main__.py @@ -162,9 +162,9 @@ def _process( ################################################################################### -def get_detectors_and_printers() -> Tuple[ - List[Type[AbstractDetector]], List[Type[AbstractPrinter]] -]: +def get_detectors_and_printers() -> ( + Tuple[List[Type[AbstractDetector]], List[Type[AbstractPrinter]]] +): detectors_ = [getattr(all_detectors, name) for name in dir(all_detectors)] detectors = [d for d in detectors_ if inspect.isclass(d) and issubclass(d, AbstractDetector)] @@ -825,7 +825,7 @@ def main_impl( default_log = logging.INFO if not args.debug else logging.DEBUG - for (l_name, l_level) in [ + for l_name, l_level in [ ("Slither", default_log), ("Contract", default_log), ("Function", default_log), diff --git a/slither/all_exceptions.py b/slither/all_exceptions.py index 1261a3bf30..d7e25d23a8 100644 --- a/slither/all_exceptions.py +++ b/slither/all_exceptions.py @@ -1,8 +1,17 @@ """ This module import all slither exceptions """ + # pylint: disable=unused-import from slither.slithir.exceptions import SlithIRError from slither.solc_parsing.exceptions import ParsingError, VariableNotFound from slither.core.exceptions import SlitherCoreError from slither.exceptions import SlitherException + +__all__ = [ + "SlithIRError", + "ParsingError", + "VariableNotFound", + "SlitherCoreError", + "SlitherException", +] diff --git a/slither/analyses/data_dependency/data_dependency.py b/slither/analyses/data_dependency/data_dependency.py index 12e809fa53..7f1556e9e4 100644 --- a/slither/analyses/data_dependency/data_dependency.py +++ b/slither/analyses/data_dependency/data_dependency.py @@ -1,6 +1,7 @@ """ Compute the data depenency between all the SSA variables """ + from collections import defaultdict from typing import Union, Set, Dict, TYPE_CHECKING, List @@ -380,8 +381,8 @@ def propagate_function( transitive_close_dependencies(function, context_key, context_key_non_ssa) # Propage data dependency data_depencencies = function.context[context_key] - for (key, values) in data_depencencies.items(): - if not key in contract.context[context_key]: + for key, values in data_depencencies.items(): + if key not in contract.context[context_key]: contract.context[context_key][key] = set(values) else: contract.context[context_key][key].union(values) @@ -413,7 +414,7 @@ def propagate_contract(contract: Contract, context_key: str, context_key_non_ssa def add_dependency(lvalue: Variable, function: Function, ir: Operation, is_protected: bool) -> None: - if not lvalue in function.context[KEY_SSA]: + if lvalue not in function.context[KEY_SSA]: function.context[KEY_SSA][lvalue] = set() if not is_protected: function.context[KEY_SSA_UNPROTECTED][lvalue] = set() @@ -493,9 +494,9 @@ def convert_to_non_ssa( ) -> Dict[SUPPORTED_TYPES, Set[SUPPORTED_TYPES]]: # Need to create new set() as its changed during iteration ret: Dict[SUPPORTED_TYPES, Set[SUPPORTED_TYPES]] = {} - for (k, values) in data_depencies.items(): + for k, values in data_depencies.items(): var = convert_variable_to_non_ssa(k) - if not var in ret: + if var not in ret: ret[var] = set() ret[var] = ret[var].union({convert_variable_to_non_ssa(v) for v in values}) diff --git a/slither/analyses/write/are_variables_written.py b/slither/analyses/write/are_variables_written.py index 2f8f83063d..bdd4298d4f 100644 --- a/slither/analyses/write/are_variables_written.py +++ b/slither/analyses/write/are_variables_written.py @@ -1,6 +1,7 @@ """ Detect if all the given variables are written in all the paths of the function """ + from collections import defaultdict from typing import Dict, Set, List, Any, Optional diff --git a/slither/core/cfg/node.py b/slither/core/cfg/node.py index 87d0e16a2e..eb995c8422 100644 --- a/slither/core/cfg/node.py +++ b/slither/core/cfg/node.py @@ -1,6 +1,7 @@ """ Node module """ + from enum import Enum from typing import Optional, List, Set, Dict, Tuple, Union, TYPE_CHECKING @@ -106,6 +107,7 @@ class NodeType(Enum): # endregion + # I am not sure why, but pylint reports a lot of "no-member" issue that are not real (Josselin) # pylint: disable=no-member class Node(SourceMapping): # pylint: disable=too-many-public-methods diff --git a/slither/core/declarations/__init__.py b/slither/core/declarations/__init__.py index 9d727da8e7..191f83da2b 100644 --- a/slither/core/declarations/__init__.py +++ b/slither/core/declarations/__init__.py @@ -23,3 +23,29 @@ from .custom_error_top_level import CustomErrorTopLevel from .custom_error import CustomError from .solidity_import_placeholder import SolidityImportPlaceHolder + +__all__ = [ + "Contract", + "Enum", + "Event", + "EventContract", + "EventTopLevel", + "Function", + "Import", + "Modifier", + "Pragma", + "SolidityVariable", + "SolidityVariableComposed", + "SolidityFunction", + "Structure", + "EnumContract", + "EnumTopLevel", + "StructureContract", + "StructureTopLevel", + "FunctionContract", + "FunctionTopLevel", + "CustomErrorContract", + "CustomErrorTopLevel", + "CustomError", + "SolidityImportPlaceHolder", +] diff --git a/slither/core/declarations/contract.py b/slither/core/declarations/contract.py index 3f97a33ed2..c37aef247d 100644 --- a/slither/core/declarations/contract.py +++ b/slither/core/declarations/contract.py @@ -1,6 +1,7 @@ """" Contract module """ + import logging from collections import defaultdict from pathlib import Path @@ -32,6 +33,7 @@ from slither.utils.type_helpers import LibraryCallType, HighLevelCallType, InternalCallType from slither.core.declarations import ( Enum, + Event, EventContract, Modifier, EnumContract, @@ -527,9 +529,9 @@ def state_variables_used_in_reentrant_targets( if self._state_variables_used_in_reentrant_targets is None: reentrant_functions = [f for f in self.functions_entry_points if f.is_reentrant] - variables_used: Dict[ - StateVariable, Set[Union[StateVariable, "Function"]] - ] = defaultdict(set) + variables_used: Dict[StateVariable, Set[Union[StateVariable, "Function"]]] = ( + defaultdict(set) + ) for function in reentrant_functions: for ir in function.all_slithir_operations(): state_variables = [v for v in ir.used if isinstance(v, StateVariable)] @@ -1454,7 +1456,7 @@ def add_constructor_variables(self) -> None: from slither.core.declarations.function_contract import FunctionContract if self.state_variables: - for (idx, variable_candidate) in enumerate(self.state_variables): + for idx, variable_candidate in enumerate(self.state_variables): if variable_candidate.expression and not variable_candidate.is_constant: constructor_variable = FunctionContract(self.compilation_unit) @@ -1484,7 +1486,7 @@ def add_constructor_variables(self) -> None: counter += 1 break - for (idx, variable_candidate) in enumerate(self.state_variables): + for idx, variable_candidate in enumerate(self.state_variables): if variable_candidate.expression and variable_candidate.is_constant: constructor_variable = FunctionContract(self.compilation_unit) diff --git a/slither/core/declarations/function.py b/slither/core/declarations/function.py index 6e8968dfb2..5962096702 100644 --- a/slither/core/declarations/function.py +++ b/slither/core/declarations/function.py @@ -1,6 +1,7 @@ """ Function module """ + import logging from abc import abstractmethod, ABCMeta from collections import namedtuple @@ -619,7 +620,7 @@ def nodes_ordered_dominators(self) -> List["Node"]: for node in self.nodes: # if node.type == NodeType.OTHER_ENTRYPOINT: - if not node in self._nodes_ordered_dominators: + if node not in self._nodes_ordered_dominators: self._compute_nodes_ordered_dominators(node) return self._nodes_ordered_dominators diff --git a/slither/core/declarations/function_contract.py b/slither/core/declarations/function_contract.py index 2e8aa3efef..87928e0305 100644 --- a/slither/core/declarations/function_contract.py +++ b/slither/core/declarations/function_contract.py @@ -1,6 +1,7 @@ """ Function module """ + from typing import Dict, TYPE_CHECKING, List, Tuple, Optional from slither.core.declarations.contract_level import ContractLevel diff --git a/slither/core/declarations/function_top_level.py b/slither/core/declarations/function_top_level.py index 39fa2d2bb7..6ba86273b6 100644 --- a/slither/core/declarations/function_top_level.py +++ b/slither/core/declarations/function_top_level.py @@ -1,6 +1,7 @@ """ Function module """ + from typing import Dict, List, Tuple, TYPE_CHECKING, Optional from slither.core.declarations import Function diff --git a/slither/core/declarations/modifier.py b/slither/core/declarations/modifier.py index 472f6ac1ee..a71dd91b96 100644 --- a/slither/core/declarations/modifier.py +++ b/slither/core/declarations/modifier.py @@ -1,6 +1,7 @@ """ Modifier module """ + from .function_contract import FunctionContract diff --git a/slither/core/declarations/solidity_import_placeholder.py b/slither/core/declarations/solidity_import_placeholder.py index 8f63600867..103bc1a83c 100644 --- a/slither/core/declarations/solidity_import_placeholder.py +++ b/slither/core/declarations/solidity_import_placeholder.py @@ -1,6 +1,7 @@ """ Special variable to model import with renaming """ + from typing import Union from slither.core.declarations import Import diff --git a/slither/core/dominators/node_dominator_tree.py b/slither/core/dominators/node_dominator_tree.py index c561cef75d..04a3a88f57 100644 --- a/slither/core/dominators/node_dominator_tree.py +++ b/slither/core/dominators/node_dominator_tree.py @@ -1,6 +1,7 @@ """ Nodes of the dominator tree """ + from typing import TYPE_CHECKING, Set, List if TYPE_CHECKING: diff --git a/slither/core/expressions/__init__.py b/slither/core/expressions/__init__.py index b162481ba2..0732c087b8 100644 --- a/slither/core/expressions/__init__.py +++ b/slither/core/expressions/__init__.py @@ -16,3 +16,29 @@ from .tuple_expression import TupleExpression from .type_conversion import TypeConversion from .unary_operation import UnaryOperation, UnaryOperationType +from .expression import Expression + +__all__ = [ + "AssignmentOperation", + "AssignmentOperationType", + "BinaryOperation", + "BinaryOperationType", + "CallExpression", + "ConditionalExpression", + "ElementaryTypeNameExpression", + "Expression", + "Identifier", + "IndexAccess", + "Literal", + "MemberAccess", + "NewArray", + "NewContract", + "NewElementaryType", + "SuperCallExpression", + "SuperIdentifier", + "SelfIdentifier", + "TupleExpression", + "TypeConversion", + "UnaryOperation", + "UnaryOperationType", +] diff --git a/slither/core/expressions/elementary_type_name_expression.py b/slither/core/expressions/elementary_type_name_expression.py index 9a93f0839a..1f34857764 100644 --- a/slither/core/expressions/elementary_type_name_expression.py +++ b/slither/core/expressions/elementary_type_name_expression.py @@ -1,6 +1,7 @@ """ This expression does nothing, if a contract used it, its probably a bug """ + from slither.core.expressions.expression import Expression from slither.core.solidity_types.type import Type from slither.core.solidity_types.elementary_type import ElementaryType diff --git a/slither/core/scope/scope.py b/slither/core/scope/scope.py index ee2a98eb3a..4f0b3db7ed 100644 --- a/slither/core/scope/scope.py +++ b/slither/core/scope/scope.py @@ -134,7 +134,10 @@ def bytecode_init( Returns: """ - getter: Callable[[SourceUnit], Dict[str, str]] = lambda x: x.bytecodes_init + + def getter(x: SourceUnit) -> Dict[str, str]: + return x.bytecodes_init + return self._generic_source_unit_getter( crytic_compile_compilation_unit, contract_name, getter ) @@ -152,7 +155,10 @@ def bytecode_runtime( Returns: """ - getter: Callable[[SourceUnit], Dict[str, str]] = lambda x: x.bytecodes_runtime + + def getter(x: SourceUnit) -> Dict[str, str]: + return x.bytecodes_runtime + return self._generic_source_unit_getter( crytic_compile_compilation_unit, contract_name, getter ) @@ -170,7 +176,10 @@ def srcmap_init( Returns: """ - getter: Callable[[SourceUnit], Dict[str, List[str]]] = lambda x: x.srcmaps_init + + def getter(x: SourceUnit) -> Dict[str, List[str]]: + return x.srcmaps_init + return self._generic_source_unit_getter( crytic_compile_compilation_unit, contract_name, getter ) @@ -188,7 +197,10 @@ def srcmap_runtime( Returns: """ - getter: Callable[[SourceUnit], Dict[str, List[str]]] = lambda x: x.srcmaps_runtime + + def getter(x: SourceUnit) -> Dict[str, List[str]]: + return x.srcmaps_runtime + return self._generic_source_unit_getter( crytic_compile_compilation_unit, contract_name, getter ) @@ -204,7 +216,10 @@ def abi(self, crytic_compile_compilation_unit: CompilationUnit, contract_name: s Returns: """ - getter: Callable[[SourceUnit], Dict[str, List[str]]] = lambda x: x.abis + + def getter(x: SourceUnit) -> Dict[str, List[str]]: + return x.abis + return self._generic_source_unit_getter( crytic_compile_compilation_unit, contract_name, getter ) diff --git a/slither/core/slither_core.py b/slither/core/slither_core.py index 1206e564bc..27a3b05757 100644 --- a/slither/core/slither_core.py +++ b/slither/core/slither_core.py @@ -1,6 +1,7 @@ """ Main module """ + import json import logging import os diff --git a/slither/core/solidity_types/__init__.py b/slither/core/solidity_types/__init__.py index a6de75bf54..15b4067e92 100644 --- a/slither/core/solidity_types/__init__.py +++ b/slither/core/solidity_types/__init__.py @@ -6,3 +6,16 @@ from .type import Type from .type_information import TypeInformation from .type_alias import TypeAlias, TypeAliasTopLevel, TypeAliasContract + +__all__ = [ + "ArrayType", + "ElementaryType", + "FunctionType", + "MappingType", + "UserDefinedType", + "Type", + "TypeInformation", + "TypeAlias", + "TypeAliasTopLevel", + "TypeAliasContract", +] diff --git a/slither/core/solidity_types/user_defined_type.py b/slither/core/solidity_types/user_defined_type.py index a9bbd40a21..ca46983734 100644 --- a/slither/core/solidity_types/user_defined_type.py +++ b/slither/core/solidity_types/user_defined_type.py @@ -9,6 +9,7 @@ from slither.core.declarations.enum import Enum from slither.core.declarations.contract import Contract + # pylint: disable=import-outside-toplevel class UserDefinedType(Type): def __init__(self, t: Union["Enum", "Contract", "Structure"]) -> None: diff --git a/slither/core/source_mapping/source_mapping.py b/slither/core/source_mapping/source_mapping.py index 41841f1e80..9cc1d7cec7 100644 --- a/slither/core/source_mapping/source_mapping.py +++ b/slither/core/source_mapping/source_mapping.py @@ -16,6 +16,7 @@ # All an object needs to do is to inherits from SourceMapping # And call set_offset at some point + # pylint: disable=too-many-instance-attributes class Source: def __init__(self, compilation_unit: "SlitherCompilationUnit") -> None: @@ -169,17 +170,17 @@ def _convert_source_mapping( if len(position) != 1: return Source(compilation_unit) - s, l, f = position[0] - s = int(s) - l = int(l) - f = int(f) + start, length, file_path = position[0] + start = int(start) + length = int(length) + file_path = int(file_path) - if f not in sourceUnits: + if file_path not in sourceUnits: new_source = Source(compilation_unit) - new_source.start = s - new_source.length = l + new_source.start = start + new_source.length = length return new_source - filename_used = sourceUnits[f] + filename_used = sourceUnits[file_path] # If possible, convert the filename to its absolute/relative version assert compilation_unit.core.crytic_compile @@ -187,17 +188,19 @@ def _convert_source_mapping( filename: Filename = compilation_unit.core.crytic_compile.filename_lookup(filename_used) is_dependency = compilation_unit.core.crytic_compile.is_dependency(filename.absolute) - (lines, starting_column, ending_column) = _compute_line(compilation_unit, filename, s, l) + (lines, starting_column, ending_column) = _compute_line( + compilation_unit, filename, start, length + ) new_source = Source(compilation_unit) - new_source.start = s - new_source.length = l + new_source.start = start + new_source.length = length new_source.filename = filename new_source.is_dependency = is_dependency new_source.lines = lines new_source.starting_column = starting_column new_source.ending_column = ending_column - new_source.end = new_source.start + l + new_source.end = new_source.start + length return new_source diff --git a/slither/core/variables/__init__.py b/slither/core/variables/__init__.py index 53872853aa..473f5e25a0 100644 --- a/slither/core/variables/__init__.py +++ b/slither/core/variables/__init__.py @@ -6,3 +6,14 @@ from .event_variable import EventVariable from .function_type_variable import FunctionTypeVariable from .structure_variable import StructureVariable + +__all__ = [ + "StateVariable", + "Variable", + "LocalVariableInitFromTuple", + "LocalVariable", + "TopLevelVariable", + "EventVariable", + "FunctionTypeVariable", + "StructureVariable", +] diff --git a/slither/core/variables/variable.py b/slither/core/variables/variable.py index 63d1a7a838..c7fd470930 100644 --- a/slither/core/variables/variable.py +++ b/slither/core/variables/variable.py @@ -1,6 +1,7 @@ """ Variable module """ + from typing import Optional, TYPE_CHECKING, List, Union, Tuple from slither.core.source_mapping.source_mapping import SourceMapping @@ -10,6 +11,7 @@ if TYPE_CHECKING: from slither.core.expressions.expression import Expression + # pylint: disable=too-many-instance-attributes class Variable(SourceMapping): def __init__(self) -> None: diff --git a/slither/detectors/abstract_detector.py b/slither/detectors/abstract_detector.py index 8baf9bb3c7..bc91814edd 100644 --- a/slither/detectors/abstract_detector.py +++ b/slither/detectors/abstract_detector.py @@ -209,7 +209,7 @@ def detect(self) -> List[Dict]: for result in results: try: self._format(self.compilation_unit, result) - if not "patches" in result: + if "patches" not in result: continue result["patches_diff"] = {} for file in result["patches"]: diff --git a/slither/detectors/all_detectors.py b/slither/detectors/all_detectors.py index 7c54844316..00ac84603e 100644 --- a/slither/detectors/all_detectors.py +++ b/slither/detectors/all_detectors.py @@ -98,3 +98,101 @@ from .statements.return_bomb import ReturnBomb from .functions.out_of_order_retryable import OutOfOrderRetryable from .statements.unused_import import UnusedImport + + +__all__ = [ + "Backdoor", + "UninitializedStateVarsDetection", + "UninitializedStorageVars", + "UninitializedLocalVars", + "VarReadUsingThis", + "ConstantPragma", + "IncorrectSolc", + "LockedEther", + "ArbitrarySendEth", + "ArbitrarySendErc20NoPermit", + "ArbitrarySendErc20Permit", + "Suicidal", + "ReentrancyBenign", + "ReentrancyReadBeforeWritten", + "ReentrancyEth", + "ReentrancyNoGas", + "ReentrancyEvent", + "UnusedStateVars", + "CouldBeConstant", + "CouldBeImmutable", + "TxOrigin", + "Assembly", + "LowLevelCalls", + "UnusedReturnValues", + "UncheckedTransfer", + "NamingConvention", + "ExternalFunction", + "ControlledDelegateCall", + "ConstantFunctionsAsm", + "ConstantFunctionsState", + "ShadowingAbstractDetection", + "StateShadowing", + "LocalShadowing", + "BuiltinSymbolShadowing", + "Timestamp", + "MultipleCallsInLoop", + "IncorrectStrictEquality", + "IncorrectERC20InterfaceDetection", + "IncorrectERC721InterfaceDetection", + "UnindexedERC20EventParameters", + "DeprecatedStandards", + "RightToLeftOverride", + "TooManyDigits", + "UncheckedLowLevel", + "UncheckedSend", + "VoidConstructor", + "TypeBasedTautology", + "BooleanEquality", + "BooleanConstantMisuse", + "DivideBeforeMultiply", + "UnprotectedUpgradeable", + "NameReused", + "UnimplementedFunctionDetection", + "MappingDeletionDetection", + "ArrayLengthAssignment", + "FunctionInitializedState", + "RedundantStatements", + "BadPRNG", + "CostlyOperationsInLoop", + "AssertStateChange", + "MissingInheritance", + "ShiftParameterMixup", + "StorageSignedIntegerArray", + "UninitializedFunctionPtrsConstructor", + "ABIEncoderV2Array", + "ArrayByReference", + "EnumConversion", + "MultipleConstructorSchemes", + "PublicMappingNested", + "ReusedBaseConstructor", + "MissingEventsAccessControl", + "MissingEventsArithmetic", + "ModifierDefaultDetection", + "PredeclarationUsageLocal", + "IncorrectUnaryExpressionDetection", + "MissingZeroAddressValidation", + "DeadCode", + "WriteAfterWrite", + "MsgValueInLoop", + "DelegatecallInLoop", + "ProtectedVariables", + "DomainSeparatorCollision", + "Codex", + "CyclomaticComplexity", + "CacheArrayLength", + "IncorrectUsingFor", + "EncodePackedCollision", + "IncorrectReturn", + "ReturnInsteadOfLeave", + "IncorrectOperatorExponentiation", + "TautologicalCompare", + "ReturnBomb", + "OutOfOrderRetryable", + "UnusedImport", +] diff --git a/slither/detectors/attributes/const_functions_asm.py b/slither/detectors/attributes/const_functions_asm.py index 01798e0858..fee2a5ffca 100644 --- a/slither/detectors/attributes/const_functions_asm.py +++ b/slither/detectors/attributes/const_functions_asm.py @@ -2,6 +2,7 @@ Module detecting constant functions Recursively check the called functions """ + from typing import List, Dict from slither.core.compilation_unit import SlitherCompilationUnit diff --git a/slither/detectors/attributes/const_functions_state.py b/slither/detectors/attributes/const_functions_state.py index d86ca7c0e1..30289b9369 100644 --- a/slither/detectors/attributes/const_functions_state.py +++ b/slither/detectors/attributes/const_functions_state.py @@ -2,6 +2,7 @@ Module detecting constant functions Recursively check the called functions """ + from typing import List, Dict from slither.core.compilation_unit import SlitherCompilationUnit diff --git a/slither/detectors/attributes/constant_pragma.py b/slither/detectors/attributes/constant_pragma.py index e391f1d56d..3d3c5bd91a 100644 --- a/slither/detectors/attributes/constant_pragma.py +++ b/slither/detectors/attributes/constant_pragma.py @@ -1,6 +1,7 @@ """ Check that the same pragma is used in all the files """ + from collections import OrderedDict from typing import List, Dict diff --git a/slither/detectors/attributes/locked_ether.py b/slither/detectors/attributes/locked_ether.py index 91ec686503..1e858154bc 100644 --- a/slither/detectors/attributes/locked_ether.py +++ b/slither/detectors/attributes/locked_ether.py @@ -1,6 +1,7 @@ """ Check if ethers are locked in the contract """ + from typing import List from slither.core.declarations import Contract, SolidityFunction @@ -97,7 +98,7 @@ def do_no_send_ether(contract: Contract) -> bool: # Add it to the list to explore # InternalCall if to follow internal call in libraries if isinstance(ir, (InternalCall, LibraryCall)): - if not ir.function in explored: + if ir.function not in explored: to_explore.append(ir.function) return True diff --git a/slither/detectors/attributes/unimplemented_interface.py b/slither/detectors/attributes/unimplemented_interface.py index 5c6c9c5f26..5231c96cf0 100644 --- a/slither/detectors/attributes/unimplemented_interface.py +++ b/slither/detectors/attributes/unimplemented_interface.py @@ -4,6 +4,7 @@ Collect all the interfaces Check for contracts which implement all interface functions but do not explicitly derive from those interfaces. """ + from typing import List from slither.detectors.abstract_detector import ( AbstractDetector, diff --git a/slither/detectors/compiler_bugs/array_by_reference.py b/slither/detectors/compiler_bugs/array_by_reference.py index 47e2af5819..5b3ad75bba 100644 --- a/slither/detectors/compiler_bugs/array_by_reference.py +++ b/slither/detectors/compiler_bugs/array_by_reference.py @@ -1,6 +1,7 @@ """ Detects the passing of arrays located in memory to functions which expect to modify arrays via storage reference. """ + from typing import List, Set, Tuple, Union from slither.core.declarations import Function @@ -133,7 +134,7 @@ def detect_calls_passing_ref_to_function( continue # Verify one of these parameters is an array in storage. - for (param, arg) in zip(ir.function.parameters, ir.arguments): + for param, arg in zip(ir.function.parameters, ir.arguments): # Verify this argument is a variable that is an array type. if not isinstance(arg, (StateVariable, LocalVariable)): continue diff --git a/slither/detectors/compiler_bugs/enum_conversion.py b/slither/detectors/compiler_bugs/enum_conversion.py index c7f1bcf4e2..4c453fff8c 100644 --- a/slither/detectors/compiler_bugs/enum_conversion.py +++ b/slither/detectors/compiler_bugs/enum_conversion.py @@ -1,6 +1,7 @@ """ Module detecting dangerous conversion to enum """ + from typing import List, Tuple from slither.core.cfg.node import Node diff --git a/slither/detectors/compiler_bugs/public_mapping_nested.py b/slither/detectors/compiler_bugs/public_mapping_nested.py index 0ae8c3d509..64cb0723cd 100644 --- a/slither/detectors/compiler_bugs/public_mapping_nested.py +++ b/slither/detectors/compiler_bugs/public_mapping_nested.py @@ -1,6 +1,7 @@ """ Module detecting public mappings with nested variables (returns incorrect values prior to 0.5.x) """ + from typing import Any, List, Union from slither.detectors.abstract_detector import ( AbstractDetector, diff --git a/slither/detectors/compiler_bugs/reused_base_constructor.py b/slither/detectors/compiler_bugs/reused_base_constructor.py index 4764dc6419..d511e44be7 100644 --- a/slither/detectors/compiler_bugs/reused_base_constructor.py +++ b/slither/detectors/compiler_bugs/reused_base_constructor.py @@ -1,6 +1,7 @@ """ Module detecting re-used base constructors in inheritance hierarchy. """ + from typing import Any, Dict, List, Tuple, Union from slither.detectors.abstract_detector import ( AbstractDetector, @@ -159,7 +160,7 @@ def _detect(self) -> List[Output]: " arguments more than once in inheritance hierarchy:\n", ] - for (calling_contract, called_by_constructor) in call_list: + for calling_contract, called_by_constructor in call_list: info += [ "\t- From ", calling_contract, diff --git a/slither/detectors/compiler_bugs/storage_ABIEncoderV2_array.py b/slither/detectors/compiler_bugs/storage_ABIEncoderV2_array.py index dd34eb5e0d..4f09aa94dc 100644 --- a/slither/detectors/compiler_bugs/storage_ABIEncoderV2_array.py +++ b/slither/detectors/compiler_bugs/storage_ABIEncoderV2_array.py @@ -1,6 +1,7 @@ """ Module detecting ABIEncoderV2 array bug """ + from typing import List, Set, Tuple from slither.detectors.abstract_detector import ( AbstractDetector, diff --git a/slither/detectors/compiler_bugs/storage_signed_integer_array.py b/slither/detectors/compiler_bugs/storage_signed_integer_array.py index cfd13cdbc9..8c918f414e 100644 --- a/slither/detectors/compiler_bugs/storage_signed_integer_array.py +++ b/slither/detectors/compiler_bugs/storage_signed_integer_array.py @@ -1,6 +1,7 @@ """ Module detecting storage signed integer array bug """ + from typing import List, Tuple, Set from slither.core.declarations import Function, Contract diff --git a/slither/detectors/compiler_bugs/uninitialized_function_ptr_in_constructor.py b/slither/detectors/compiler_bugs/uninitialized_function_ptr_in_constructor.py index 826b671bd1..09155d708f 100644 --- a/slither/detectors/compiler_bugs/uninitialized_function_ptr_in_constructor.py +++ b/slither/detectors/compiler_bugs/uninitialized_function_ptr_in_constructor.py @@ -1,6 +1,7 @@ """ Module detecting uninitialized function pointer calls in constructors """ + from typing import Any, List, Union from slither.detectors.abstract_detector import ( AbstractDetector, diff --git a/slither/detectors/erc/erc20/incorrect_erc20_interface.py b/slither/detectors/erc/erc20/incorrect_erc20_interface.py index a17f04e8c7..8a99a4a95d 100644 --- a/slither/detectors/erc/erc20/incorrect_erc20_interface.py +++ b/slither/detectors/erc/erc20/incorrect_erc20_interface.py @@ -2,6 +2,7 @@ Detect incorrect erc20 interface. Some contracts do not return a bool on transfer/transferFrom/approve, which may lead to preventing the contract to be used with contracts compiled with recent solc (>0.4.22) """ + from typing import List, Tuple from slither.core.declarations.contract import Contract diff --git a/slither/detectors/erc/incorrect_erc721_interface.py b/slither/detectors/erc/incorrect_erc721_interface.py index e05f3ce8e9..d6e49fc7ca 100644 --- a/slither/detectors/erc/incorrect_erc721_interface.py +++ b/slither/detectors/erc/incorrect_erc721_interface.py @@ -1,6 +1,7 @@ """ Detect incorrect erc721 interface. """ + from typing import Any, List, Tuple, Union from slither.detectors.abstract_detector import ( AbstractDetector, diff --git a/slither/detectors/erc/unindexed_event_parameters.py b/slither/detectors/erc/unindexed_event_parameters.py index 6e91b0fb36..fdd5045b37 100644 --- a/slither/detectors/erc/unindexed_event_parameters.py +++ b/slither/detectors/erc/unindexed_event_parameters.py @@ -1,6 +1,7 @@ """ Detect mistakenly un-indexed ERC20 event parameters """ + from typing import Any, List, Tuple, Union from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification from slither.core.declarations.contract import Contract @@ -84,7 +85,7 @@ def _detect(self) -> List[Output]: unindexed_params = self.detect_erc20_unindexed_event_params(c) if unindexed_params: # Add each problematic event definition to our result list - for (event, parameter) in unindexed_params: + for event, parameter in unindexed_params: info = [ "ERC20 event ", diff --git a/slither/detectors/functions/arbitrary_send_eth.py b/slither/detectors/functions/arbitrary_send_eth.py index f6c688a3fc..7cd85e0c48 100644 --- a/slither/detectors/functions/arbitrary_send_eth.py +++ b/slither/detectors/functions/arbitrary_send_eth.py @@ -9,6 +9,7 @@ TODO: dont report if the value is tainted by msg.value """ + from typing import Any, Tuple, Union, List from slither.analyses.data_dependency.data_dependency import is_tainted, is_dependent @@ -135,7 +136,7 @@ def _detect(self) -> List[Output]: for c in self.contracts: arbitrary_send_result = detect_arbitrary_send(c) - for (func, nodes) in arbitrary_send_result: + for func, nodes in arbitrary_send_result: info = [func, " sends eth to arbitrary user\n"] info += ["\tDangerous calls:\n"] diff --git a/slither/detectors/functions/dead_code.py b/slither/detectors/functions/dead_code.py index 98eb97ff7e..905881892c 100644 --- a/slither/detectors/functions/dead_code.py +++ b/slither/detectors/functions/dead_code.py @@ -1,6 +1,7 @@ """ Module detecting dead code """ + from typing import List, Tuple from slither.core.declarations import Function, FunctionContract, Contract diff --git a/slither/detectors/functions/modifier.py b/slither/detectors/functions/modifier.py index 7f14872663..a05538b05a 100644 --- a/slither/detectors/functions/modifier.py +++ b/slither/detectors/functions/modifier.py @@ -5,6 +5,7 @@ are in the outermost scope, they do not guarantee a revert, so a default value can still be returned. """ + from typing import List from slither.detectors.abstract_detector import ( AbstractDetector, diff --git a/slither/detectors/functions/permit_domain_signature_collision.py b/slither/detectors/functions/permit_domain_signature_collision.py index 39543fb496..a465795499 100644 --- a/slither/detectors/functions/permit_domain_signature_collision.py +++ b/slither/detectors/functions/permit_domain_signature_collision.py @@ -1,6 +1,7 @@ """ Module detecting EIP-2612 domain separator collision """ + from typing import Union, List from slither.core.declarations import Function diff --git a/slither/detectors/functions/protected_variable.py b/slither/detectors/functions/protected_variable.py index 5796729262..29ab5a3e30 100644 --- a/slither/detectors/functions/protected_variable.py +++ b/slither/detectors/functions/protected_variable.py @@ -3,6 +3,7 @@ A suicidal contract is an unprotected function that calls selfdestruct """ + from typing import List from slither.core.declarations import Function, Contract diff --git a/slither/detectors/functions/suicidal.py b/slither/detectors/functions/suicidal.py index f0af978ec7..95b7bcbfcd 100644 --- a/slither/detectors/functions/suicidal.py +++ b/slither/detectors/functions/suicidal.py @@ -3,6 +3,7 @@ A suicidal contract is an unprotected function that calls selfdestruct """ + from typing import List from slither.core.declarations.contract import Contract diff --git a/slither/detectors/functions/unimplemented.py b/slither/detectors/functions/unimplemented.py index 27a2d94a98..35b12e93e0 100644 --- a/slither/detectors/functions/unimplemented.py +++ b/slither/detectors/functions/unimplemented.py @@ -7,6 +7,7 @@ Consider public state variables as implemented functions Do not consider fallback function or constructor """ + from typing import List, Set from slither.core.declarations import Function diff --git a/slither/detectors/operations/block_timestamp.py b/slither/detectors/operations/block_timestamp.py index d5c2c8df78..f52429fa96 100644 --- a/slither/detectors/operations/block_timestamp.py +++ b/slither/detectors/operations/block_timestamp.py @@ -2,6 +2,7 @@ Module detecting dangerous use of block.timestamp """ + from typing import List, Tuple from slither.analyses.data_dependency.data_dependency import is_dependent @@ -81,7 +82,7 @@ def _detect(self) -> List[Output]: for c in self.contracts: dangerous_timestamp = _detect_dangerous_timestamp(c) - for (func, nodes) in dangerous_timestamp: + for func, nodes in dangerous_timestamp: info: DETECTOR_INFO = [func, " uses timestamp for comparisons\n"] diff --git a/slither/detectors/operations/incorrect_exp.py b/slither/detectors/operations/incorrect_exp.py index 6188f5cb16..f1b4c0cda5 100644 --- a/slither/detectors/operations/incorrect_exp.py +++ b/slither/detectors/operations/incorrect_exp.py @@ -1,6 +1,7 @@ """ Module detecting incorrect operator usage for exponentiation where bitwise xor '^' is used instead of '**' """ + from typing import Tuple, List, Union from slither.core.cfg.node import Node @@ -82,7 +83,7 @@ def _detect(self) -> List[Output]: results: List[Output] = [] for c in self.compilation_unit.contracts_derived: res = _detect_incorrect_operator(c) - for (func, node) in res: + for func, node in res: info: DETECTOR_INFO = [ func, " has bitwise-xor operator ^ instead of the exponentiation operator **: \n", diff --git a/slither/detectors/operations/low_level_calls.py b/slither/detectors/operations/low_level_calls.py index 463c748757..1bd7fdc17a 100644 --- a/slither/detectors/operations/low_level_calls.py +++ b/slither/detectors/operations/low_level_calls.py @@ -1,6 +1,7 @@ """ Module detecting usage of low level calls """ + from typing import List, Tuple from slither.detectors.abstract_detector import ( AbstractDetector, diff --git a/slither/detectors/operations/missing_events_access_control.py b/slither/detectors/operations/missing_events_access_control.py index 853eafd734..86d229a913 100644 --- a/slither/detectors/operations/missing_events_access_control.py +++ b/slither/detectors/operations/missing_events_access_control.py @@ -2,6 +2,7 @@ Module detecting missing events for critical contract parameters set by owners and used in access control """ + from typing import List, Tuple from slither.analyses.data_dependency.data_dependency import is_tainted @@ -103,9 +104,9 @@ def _detect(self) -> List[Output]: results = [] for contract in self.compilation_unit.contracts_derived: missing_events = self._detect_missing_events(contract) - for (function, nodes) in missing_events: + for function, nodes in missing_events: info: DETECTOR_INFO = [function, " should emit an event for: \n"] - for (node, _sv, _mod) in nodes: + for node, _sv, _mod in nodes: info += ["\t- ", node, " \n"] res = self.generate_result(info) results.append(res) diff --git a/slither/detectors/operations/missing_events_arithmetic.py b/slither/detectors/operations/missing_events_arithmetic.py index c17ed32a3a..b3fb46af09 100644 --- a/slither/detectors/operations/missing_events_arithmetic.py +++ b/slither/detectors/operations/missing_events_arithmetic.py @@ -2,6 +2,7 @@ Module detecting missing events for critical contract parameters set by owners and used in arithmetic """ + from typing import List, Tuple from slither.analyses.data_dependency.data_dependency import is_tainted @@ -125,9 +126,9 @@ def _detect(self) -> List[Output]: results = [] for contract in self.compilation_unit.contracts_derived: missing_events = self._detect_missing_events(contract) - for (function, nodes) in missing_events: + for function, nodes in missing_events: info: DETECTOR_INFO = [function, " should emit an event for: \n"] - for (node, _) in nodes: + for node, _ in nodes: info += ["\t- ", node, " \n"] res = self.generate_result(info) results.append(res) diff --git a/slither/detectors/operations/missing_zero_address_validation.py b/slither/detectors/operations/missing_zero_address_validation.py index 4feac9d0ce..2ad048ed88 100644 --- a/slither/detectors/operations/missing_zero_address_validation.py +++ b/slither/detectors/operations/missing_zero_address_validation.py @@ -2,6 +2,7 @@ Module detecting missing zero address validation """ + from collections import defaultdict from typing import DefaultDict, List, Tuple, Union @@ -157,7 +158,7 @@ def _detect(self) -> List[Output]: results = [] for contract in self.compilation_unit.contracts_derived: missing_zero_address_validation = self._detect_missing_zero_address_validation(contract) - for (_, var_nodes) in missing_zero_address_validation: + for _, var_nodes in missing_zero_address_validation: for var, nodes in var_nodes.items(): info: DETECTOR_INFO = [var, " lacks a zero-check on ", ":\n"] for node in nodes: diff --git a/slither/detectors/operations/unchecked_low_level_return_values.py b/slither/detectors/operations/unchecked_low_level_return_values.py index c1fb1a8688..b3613154c9 100644 --- a/slither/detectors/operations/unchecked_low_level_return_values.py +++ b/slither/detectors/operations/unchecked_low_level_return_values.py @@ -1,6 +1,7 @@ """ Module detecting unused return values from low level """ + from typing import List from slither.core.cfg.node import Node diff --git a/slither/detectors/operations/unused_return_values.py b/slither/detectors/operations/unused_return_values.py index 8b6ca1f26b..d2b6cf8f05 100644 --- a/slither/detectors/operations/unused_return_values.py +++ b/slither/detectors/operations/unused_return_values.py @@ -1,6 +1,7 @@ """ Module detecting unused return values from external calls """ + from typing import List from slither.core.cfg.node import Node, NodeType diff --git a/slither/detectors/reentrancy/reentrancy.py b/slither/detectors/reentrancy/reentrancy.py index 8dd9aecc05..0b0700643a 100644 --- a/slither/detectors/reentrancy/reentrancy.py +++ b/slither/detectors/reentrancy/reentrancy.py @@ -4,6 +4,7 @@ Based on heuristics, it may lead to FP and FN Iterate over all the nodes of the graph until reaching a fixpoint """ + from collections import defaultdict from typing import Set, Dict, List, Tuple, Optional diff --git a/slither/detectors/reentrancy/reentrancy_benign.py b/slither/detectors/reentrancy/reentrancy_benign.py index 25fe0ff038..122d79df6a 100644 --- a/slither/detectors/reentrancy/reentrancy_benign.py +++ b/slither/detectors/reentrancy/reentrancy_benign.py @@ -4,6 +4,7 @@ Based on heuristics, it may lead to FP and FN Iterate over all the nodes of the graph until reaching a fixpoint """ + from collections import namedtuple, defaultdict from typing import DefaultDict, Set, List @@ -106,14 +107,14 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches info = ["Reentrancy in ", func, ":\n"] info += ["\tExternal calls:\n"] - for (call_info, calls_list) in calls: + for call_info, calls_list in calls: info += ["\t- ", call_info, "\n"] for call_list_info in calls_list: if call_list_info != call_info: info += ["\t\t- ", call_list_info, "\n"] if calls != send_eth and send_eth: info += ["\tExternal calls sending eth:\n"] - for (call_info, calls_list) in send_eth: + for call_info, calls_list in send_eth: info += ["\t- ", call_info, "\n"] for call_list_info in calls_list: if call_list_info != call_info: @@ -132,7 +133,7 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches res.add(func) # Add all underlying calls in the function which are potentially problematic. - for (call_info, calls_list) in calls: + for call_info, calls_list in calls: res.add(call_info, {"underlying_type": "external_calls"}) for call_list_info in calls_list: if call_list_info != call_info: @@ -145,7 +146,7 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches # If the calls are not the same ones that send eth, add the eth sending nodes. if calls != send_eth: - for (call_info, calls_list) in calls: + for call_info, calls_list in calls: res.add(call_info, {"underlying_type": "external_calls_sending_eth"}) for call_list_info in calls_list: if call_list_info != call_info: diff --git a/slither/detectors/reentrancy/reentrancy_eth.py b/slither/detectors/reentrancy/reentrancy_eth.py index ccb6688372..e8711e20a3 100644 --- a/slither/detectors/reentrancy/reentrancy_eth.py +++ b/slither/detectors/reentrancy/reentrancy_eth.py @@ -4,6 +4,7 @@ Based on heuristics, it may lead to FP and FN Iterate over all the nodes of the graph until reaching a fixpoint """ + from collections import namedtuple, defaultdict from typing import List, Dict, Set @@ -60,7 +61,7 @@ def find_reentrancies(self) -> Dict[FindingKey, Set[FindingValue]]: for f in contract.functions_and_modifiers_declared: for node in f.nodes: # dead code - if not self.KEY in node.context: + if self.KEY not in node.context: continue if node.context[self.KEY].calls and node.context[self.KEY].send_eth: if not any(n != node for n in node.context[self.KEY].send_eth): @@ -114,14 +115,14 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches,too-many info = ["Reentrancy in ", func, ":\n"] info += ["\tExternal calls:\n"] - for (call_info, calls_list) in calls: + for call_info, calls_list in calls: info += ["\t- ", call_info, "\n"] for call_list_info in calls_list: if call_list_info != call_info: info += ["\t\t- ", call_list_info, "\n"] if calls != send_eth and send_eth: info += ["\tExternal calls sending eth:\n"] - for (call_info, calls_list) in send_eth: + for call_info, calls_list in send_eth: info += ["\t- ", call_info, "\n"] for call_list_info in calls_list: if call_list_info != call_info: @@ -148,7 +149,7 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches,too-many res.add(func) # Add all underlying calls in the function which are potentially problematic. - for (call_info, calls_list) in calls: + for call_info, calls_list in calls: res.add(call_info, {"underlying_type": "external_calls"}) for call_list_info in calls_list: if call_list_info != call_info: @@ -159,7 +160,7 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches,too-many # If the calls are not the same ones that send eth, add the eth sending nodes. if calls != send_eth: - for (call_info, calls_list) in send_eth: + for call_info, calls_list in send_eth: res.add(call_info, {"underlying_type": "external_calls_sending_eth"}) for call_list_info in calls_list: if call_list_info != call_info: diff --git a/slither/detectors/reentrancy/reentrancy_events.py b/slither/detectors/reentrancy/reentrancy_events.py index ac9c049c4c..2752605123 100644 --- a/slither/detectors/reentrancy/reentrancy_events.py +++ b/slither/detectors/reentrancy/reentrancy_events.py @@ -4,6 +4,7 @@ Based on heuristics, it may lead to FP and FN Iterate over all the nodes of the graph until reaching a fixpoint """ + from collections import namedtuple, defaultdict from typing import DefaultDict, List, Set @@ -119,14 +120,14 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches info = ["Reentrancy in ", func, ":\n"] info += ["\tExternal calls:\n"] - for (call_info, calls_list) in calls: + for call_info, calls_list in calls: info += ["\t- ", call_info, "\n"] for call_list_info in calls_list: if call_list_info != call_info: info += ["\t\t- ", call_list_info, "\n"] if calls != send_eth and send_eth: info += ["\tExternal calls sending eth:\n"] - for (call_info, calls_list) in send_eth: + for call_info, calls_list in send_eth: info += ["\t- ", call_info, "\n"] for call_list_info in calls_list: if call_list_info != call_info: @@ -145,7 +146,7 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches res.add(func) # Add all underlying calls in the function which are potentially problematic. - for (call_info, calls_list) in calls: + for call_info, calls_list in calls: res.add(call_info, {"underlying_type": "external_calls"}) for call_list_info in calls_list: if call_list_info != call_info: @@ -158,7 +159,7 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches # If the calls are not the same ones that send eth, add the eth sending nodes. if calls != send_eth: - for (call_info, calls_list) in send_eth: + for call_info, calls_list in send_eth: res.add(call_info, {"underlying_type": "external_calls_sending_eth"}) for call_list_info in calls_list: if call_list_info != call_info: diff --git a/slither/detectors/reentrancy/reentrancy_no_gas.py b/slither/detectors/reentrancy/reentrancy_no_gas.py index c559d76df8..1cea366c37 100644 --- a/slither/detectors/reentrancy/reentrancy_no_gas.py +++ b/slither/detectors/reentrancy/reentrancy_no_gas.py @@ -4,6 +4,7 @@ Based on heuristics, it may lead to FP and FN Iterate over all the nodes of the graph until reaching a fixpoint """ + from collections import namedtuple, defaultdict from typing import DefaultDict, List, Union, Set @@ -117,14 +118,14 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches,too-many info = ["Reentrancy in ", func, ":\n"] info += ["\tExternal calls:\n"] - for (call_info, calls_list) in calls: + for call_info, calls_list in calls: info += ["\t- ", call_info, "\n"] for call_list_info in calls_list: if call_list_info != call_info: info += ["\t\t- ", call_list_info, "\n"] if calls != send_eth and send_eth: info += ["\tExternal calls sending eth:\n"] - for (call_info, calls_list) in send_eth: + for call_info, calls_list in send_eth: info += ["\t- ", call_info, "\n"] for call_list_info in calls_list: if call_list_info != call_info: @@ -165,7 +166,7 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches,too-many res.add(func) # Add all underlying calls in the function which are potentially problematic. - for (call_info, calls_list) in calls: + for call_info, calls_list in calls: res.add(call_info, {"underlying_type": "external_calls"}) for call_list_info in calls_list: if call_list_info != call_info: @@ -178,7 +179,7 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches,too-many # If the calls are not the same ones that send eth, add the eth sending nodes. if calls != send_eth: - for (call_info, calls_list) in send_eth: + for call_info, calls_list in send_eth: res.add(call_info, {"underlying_type": "external_calls_sending_eth"}) for call_list_info in calls_list: if call_list_info != call_info: diff --git a/slither/detectors/reentrancy/reentrancy_read_before_write.py b/slither/detectors/reentrancy/reentrancy_read_before_write.py index c149d5a4af..66f73e1e8d 100644 --- a/slither/detectors/reentrancy/reentrancy_read_before_write.py +++ b/slither/detectors/reentrancy/reentrancy_read_before_write.py @@ -4,6 +4,7 @@ Based on heuristics, it may lead to FP and FN Iterate over all the nodes of the graph until reaching a fixpoint """ + from collections import namedtuple, defaultdict from typing import Dict, Set, List @@ -110,7 +111,7 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches info = ["Reentrancy in ", func, ":\n"] info += ["\tExternal calls:\n"] - for (call_info, calls_list) in calls: + for call_info, calls_list in calls: info += ["\t- ", call_info, "\n"] for call_list_info in calls_list: if call_list_info != call_info: @@ -137,7 +138,7 @@ def _detect(self) -> List[Output]: # pylint: disable=too-many-branches res.add(func) # Add all underlying calls in the function which are potentially problematic. - for (call_info, calls_list) in calls: + for call_info, calls_list in calls: res.add(call_info, {"underlying_type": "external_calls"}) for call_list_info in calls_list: if call_list_info != call_info: diff --git a/slither/detectors/shadowing/abstract.py b/slither/detectors/shadowing/abstract.py index d019d0f252..cbe68be992 100644 --- a/slither/detectors/shadowing/abstract.py +++ b/slither/detectors/shadowing/abstract.py @@ -2,6 +2,7 @@ Module detecting shadowing variables on abstract contract Recursively check the called functions """ + from typing import List from slither.core.declarations import Contract diff --git a/slither/detectors/shadowing/builtin_symbols.py b/slither/detectors/shadowing/builtin_symbols.py index ab54861053..151ca10310 100644 --- a/slither/detectors/shadowing/builtin_symbols.py +++ b/slither/detectors/shadowing/builtin_symbols.py @@ -1,6 +1,7 @@ """ Module detecting reserved keyword shadowing """ + from typing import List, Tuple, Union, Optional from slither.core.declarations import Function, Event diff --git a/slither/detectors/shadowing/local.py b/slither/detectors/shadowing/local.py index d67b5f688b..62ee407187 100644 --- a/slither/detectors/shadowing/local.py +++ b/slither/detectors/shadowing/local.py @@ -1,6 +1,7 @@ """ Module detecting local variable shadowing """ + from typing import List, Tuple, Union from slither.core.declarations.contract import Contract @@ -64,9 +65,7 @@ class LocalShadowing(AbstractDetector): OVERSHADOWED_RETURN_VARIABLE = "return variable" # pylint: disable=too-many-branches - def detect_shadowing_definitions( - self, contract: Contract - ) -> List[ + def detect_shadowing_definitions(self, contract: Contract) -> List[ Union[ Tuple[LocalVariable, List[Tuple[str, StateVariable]]], Tuple[LocalVariable, List[Tuple[str, FunctionContract]]], diff --git a/slither/detectors/source/rtlo.py b/slither/detectors/source/rtlo.py index b020f69f9f..5ed6befd15 100644 --- a/slither/detectors/source/rtlo.py +++ b/slither/detectors/source/rtlo.py @@ -82,7 +82,9 @@ def _detect(self) -> List[Output]: idx = start_index + result_index relative = self.slither.crytic_compile.filename_lookup(filename).relative - info: DETECTOR_INFO = f"{relative} contains a unicode right-to-left-override character at byte offset {idx}:\n" + info: DETECTOR_INFO = ( + f"{relative} contains a unicode right-to-left-override character at byte offset {idx}:\n" + ) # We have a patch, so pattern.find will return at least one result diff --git a/slither/detectors/statements/array_length_assignment.py b/slither/detectors/statements/array_length_assignment.py index 70dc5aadbb..97c57ef548 100644 --- a/slither/detectors/statements/array_length_assignment.py +++ b/slither/detectors/statements/array_length_assignment.py @@ -1,6 +1,7 @@ """ Module detecting assignment of array length """ + from typing import List, Set, Union from slither.core.variables import Variable diff --git a/slither/detectors/statements/assembly.py b/slither/detectors/statements/assembly.py index 25b5d8034a..c4e1c6a977 100644 --- a/slither/detectors/statements/assembly.py +++ b/slither/detectors/statements/assembly.py @@ -1,6 +1,7 @@ """ Module detecting usage of inline assembly """ + from typing import List, Tuple from slither.core.cfg.node import Node, NodeType diff --git a/slither/detectors/statements/assert_state_change.py b/slither/detectors/statements/assert_state_change.py index 769d730b82..d9a926dde8 100644 --- a/slither/detectors/statements/assert_state_change.py +++ b/slither/detectors/statements/assert_state_change.py @@ -1,6 +1,7 @@ """ Module detecting state changes in assert calls """ + from typing import List, Tuple from slither.core.cfg.node import Node @@ -90,7 +91,7 @@ def _detect(self) -> List[Output]: results = [] for contract in self.contracts: assert_state_change = detect_assert_state_change(contract) - for (func, node) in assert_state_change: + for func, node in assert_state_change: info: DETECTOR_INFO = [ func, " has an assert() call which possibly changes state.\n", diff --git a/slither/detectors/statements/boolean_constant_equality.py b/slither/detectors/statements/boolean_constant_equality.py index 97eb14aa5c..ea56bec52a 100644 --- a/slither/detectors/statements/boolean_constant_equality.py +++ b/slither/detectors/statements/boolean_constant_equality.py @@ -1,6 +1,7 @@ """ Module detecting misuse of Boolean constants """ + from typing import List, Set, Tuple from slither.core.cfg.node import Node @@ -86,7 +87,7 @@ def _detect(self) -> List[Output]: results = [] for contract in self.contracts: boolean_constant_misuses = self._detect_boolean_equality(contract) - for (func, nodes) in boolean_constant_misuses: + for func, nodes in boolean_constant_misuses: for node in nodes: info: DETECTOR_INFO = [ func, diff --git a/slither/detectors/statements/boolean_constant_misuse.py b/slither/detectors/statements/boolean_constant_misuse.py index 093e43fee6..8e7157d9bd 100644 --- a/slither/detectors/statements/boolean_constant_misuse.py +++ b/slither/detectors/statements/boolean_constant_misuse.py @@ -1,6 +1,7 @@ """ Module detecting misuse of Boolean constants """ + from typing import List, Set, Tuple from slither.core.cfg.node import Node, NodeType @@ -122,7 +123,7 @@ def _detect(self) -> List[Output]: results = [] for contract in self.contracts: boolean_constant_misuses = self._detect_boolean_constant_misuses(contract) - for (func, nodes) in boolean_constant_misuses: + for func, nodes in boolean_constant_misuses: for node in nodes: info: DETECTOR_INFO = [ func, diff --git a/slither/detectors/statements/deprecated_calls.py b/slither/detectors/statements/deprecated_calls.py index 5e066c751e..8686b41785 100644 --- a/slither/detectors/statements/deprecated_calls.py +++ b/slither/detectors/statements/deprecated_calls.py @@ -1,6 +1,7 @@ """ Module detecting deprecated standards. """ + from typing import List, Tuple, Union from slither.core.cfg.node import Node, NodeType @@ -127,9 +128,7 @@ def detect_deprecated_references_in_node( return results - def detect_deprecated_references_in_contract( - self, contract: Contract - ) -> List[ + def detect_deprecated_references_in_contract(self, contract: Contract) -> List[ Union[ Tuple[StateVariable, List[Tuple[str, str, str]]], Tuple[Node, List[Tuple[Union[str, NodeType], str, str]]], @@ -138,7 +137,8 @@ def detect_deprecated_references_in_contract( """Detects the usage of any deprecated built-in symbols. Returns: - list of tuple: (state_variable | node, (detecting_signature, original_text, recommended_text))""" + list of tuple: (state_variable | node, (detecting_signature, original_text, recommended_text)) + """ results: List[ Union[ Tuple[StateVariable, List[Tuple[str, str, str]]], @@ -192,7 +192,7 @@ def _detect(self) -> List[Output]: deprecated_entries = deprecated_reference[1] info: DETECTOR_INFO = ["Deprecated standard detected ", source_object, ":\n"] - for (_dep_id, original_desc, recommended_disc) in deprecated_entries: + for _dep_id, original_desc, recommended_disc in deprecated_entries: info += [ f'\t- Usage of "{original_desc}" should be replaced with "{recommended_disc}"\n' ] diff --git a/slither/detectors/statements/divide_before_multiply.py b/slither/detectors/statements/divide_before_multiply.py index e33477135d..2ca9d02a5f 100644 --- a/slither/detectors/statements/divide_before_multiply.py +++ b/slither/detectors/statements/divide_before_multiply.py @@ -1,6 +1,7 @@ """ Module detecting possible loss of precision due to divide before multiple """ + from collections import defaultdict from typing import DefaultDict, List, Tuple @@ -193,7 +194,7 @@ def _detect(self) -> List[Output]: for contract in self.contracts: divisions_before_multiplications = detect_divide_before_multiply(contract) if divisions_before_multiplications: - for (func, nodes) in divisions_before_multiplications: + for func, nodes in divisions_before_multiplications: info: DETECTOR_INFO = [ func, diff --git a/slither/detectors/statements/incorrect_strict_equality.py b/slither/detectors/statements/incorrect_strict_equality.py index ae06d7bf3b..5eb51cfcd1 100644 --- a/slither/detectors/statements/incorrect_strict_equality.py +++ b/slither/detectors/statements/incorrect_strict_equality.py @@ -2,6 +2,7 @@ Module detecting dangerous strict equality """ + from typing import Any, Dict, List, Union from slither.analyses.data_dependency.data_dependency import is_dependent_ssa from slither.core.declarations import Function diff --git a/slither/detectors/statements/mapping_deletion.py b/slither/detectors/statements/mapping_deletion.py index 0940d5a07b..4d6a0817dd 100644 --- a/slither/detectors/statements/mapping_deletion.py +++ b/slither/detectors/statements/mapping_deletion.py @@ -1,6 +1,7 @@ """ Detect deletion on structure containing a mapping """ + from typing import List, Tuple from slither.core.cfg.node import Node @@ -98,7 +99,7 @@ def _detect(self) -> List[Output]: results = [] for c in self.contracts: mapping = MappingDeletionDetection.detect_mapping_deletion(c) - for (func, struct, node) in mapping: + for func, struct, node in mapping: info: DETECTOR_INFO = [func, " deletes ", struct, " which contains a mapping:\n"] info += ["\t-", node, "\n"] diff --git a/slither/detectors/statements/redundant_statements.py b/slither/detectors/statements/redundant_statements.py index cebaecebeb..02d617a9cc 100644 --- a/slither/detectors/statements/redundant_statements.py +++ b/slither/detectors/statements/redundant_statements.py @@ -1,6 +1,7 @@ """ Module detecting redundant statements. """ + from typing import List from slither.core.cfg.node import Node, NodeType diff --git a/slither/detectors/statements/tx_origin.py b/slither/detectors/statements/tx_origin.py index 49bf6006d1..7291e97585 100644 --- a/slither/detectors/statements/tx_origin.py +++ b/slither/detectors/statements/tx_origin.py @@ -1,6 +1,7 @@ """ Module detecting usage of `tx.origin` in a conditional node """ + from typing import List, Tuple from slither.core.cfg.node import Node diff --git a/slither/detectors/statements/type_based_tautology.py b/slither/detectors/statements/type_based_tautology.py index 2e0fc84806..0ac5032e5e 100644 --- a/slither/detectors/statements/type_based_tautology.py +++ b/slither/detectors/statements/type_based_tautology.py @@ -1,6 +1,7 @@ """ Module detecting tautologies and contradictions based on types in comparison operations over integers """ + from typing import List, Set, Tuple from slither.core.cfg.node import Node @@ -163,7 +164,7 @@ def _detect(self) -> List[Output]: for contract in self.contracts: tautologies = self.detect_type_based_tautologies(contract) if tautologies: - for (func, nodes) in tautologies: + for func, nodes in tautologies: for node in nodes: info = [func, " contains a tautology or contradiction:\n"] info += ["\t- ", node, "\n"] diff --git a/slither/detectors/statements/unary.py b/slither/detectors/statements/unary.py index 9c0add2389..3b1be5b0aa 100644 --- a/slither/detectors/statements/unary.py +++ b/slither/detectors/statements/unary.py @@ -1,6 +1,7 @@ """ Module detecting the incorrect use of unary expressions """ + from typing import List from slither.core.expressions.assignment_operation import AssignmentOperation @@ -14,6 +15,7 @@ from slither.utils.output import Output from slither.visitors.expression.expression import ExpressionVisitor + # pylint: disable=too-few-public-methods class InvalidUnaryExpressionDetector(ExpressionVisitor): def __init__(self, expression: Expression) -> None: diff --git a/slither/detectors/statements/unused_import.py b/slither/detectors/statements/unused_import.py index d3447dcd81..f76fa08f44 100644 --- a/slither/detectors/statements/unused_import.py +++ b/slither/detectors/statements/unused_import.py @@ -2,6 +2,7 @@ from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification, Output from slither.core.scope.scope import FileScope + # pylint: disable=protected-access,too-many-nested-blocks class UnusedImport(AbstractDetector): """ diff --git a/slither/detectors/variables/function_init_state_variables.py b/slither/detectors/variables/function_init_state_variables.py index e440a4f964..a3bcebff9e 100644 --- a/slither/detectors/variables/function_init_state_variables.py +++ b/slither/detectors/variables/function_init_state_variables.py @@ -1,6 +1,7 @@ """ Module detecting state variables initializing from an immediate function call (prior to constructor run). """ + from typing import List from slither.core.declarations.contract import Contract diff --git a/slither/detectors/variables/predeclaration_usage_local.py b/slither/detectors/variables/predeclaration_usage_local.py index 9816dd6e24..fc3c3d9f55 100644 --- a/slither/detectors/variables/predeclaration_usage_local.py +++ b/slither/detectors/variables/predeclaration_usage_local.py @@ -1,6 +1,7 @@ """ Module detecting any path leading to usage of a local variable before it is declared. """ + from typing import List, Set, Tuple from slither.core.cfg.node import Node @@ -85,7 +86,7 @@ def detect_predeclared_local_usage( if node.variable_declaration: already_declared = already_declared | {node.variable_declaration} - if not node in self.fix_point_information: + if node not in self.fix_point_information: self.fix_point_information[node] = [] # If we already explored this node with the same information @@ -150,7 +151,7 @@ def _detect(self) -> List[Output]: for contract in self.contracts: predeclared_usages = self.detect_predeclared_in_contract(contract) if predeclared_usages: - for (predeclared_usage_function, predeclared_usage_nodes) in predeclared_usages: + for predeclared_usage_function, predeclared_usage_nodes in predeclared_usages: for ( predeclared_usage_node, predeclared_usage_local_variable, diff --git a/slither/detectors/variables/unchanged_state_variables.py b/slither/detectors/variables/unchanged_state_variables.py index 5771d96303..4ee33a27bf 100644 --- a/slither/detectors/variables/unchanged_state_variables.py +++ b/slither/detectors/variables/unchanged_state_variables.py @@ -1,6 +1,7 @@ """ Module detecting state variables that could be declared as constant """ + from typing import Set, List from packaging import version from slither.core.compilation_unit import SlitherCompilationUnit diff --git a/slither/detectors/variables/uninitialized_local_variables.py b/slither/detectors/variables/uninitialized_local_variables.py index 0aa5579f88..83cc5dfbb8 100644 --- a/slither/detectors/variables/uninitialized_local_variables.py +++ b/slither/detectors/variables/uninitialized_local_variables.py @@ -4,6 +4,7 @@ Recursively explore the CFG to only report uninitialized local variables that are read before being written """ + from typing import List from slither.core.cfg.node import Node, NodeType @@ -117,7 +118,7 @@ def _detect(self) -> List[Output]: function.entry_point.context[self.key] = uninitialized_local_variables self._detect_uninitialized(function, function.entry_point, []) all_results = list(set(self.results)) - for (function, uninitialized_local_variable) in all_results: + for function, uninitialized_local_variable in all_results: info = [ uninitialized_local_variable, diff --git a/slither/detectors/variables/uninitialized_state_variables.py b/slither/detectors/variables/uninitialized_state_variables.py index 13cf110521..ecec42a822 100644 --- a/slither/detectors/variables/uninitialized_state_variables.py +++ b/slither/detectors/variables/uninitialized_state_variables.py @@ -8,6 +8,7 @@ Only analyze "leaf" contracts (contracts that are not inherited by another contract) """ + from typing import List, Tuple from slither.core.declarations import Function diff --git a/slither/detectors/variables/uninitialized_storage_variables.py b/slither/detectors/variables/uninitialized_storage_variables.py index 9caa5b88fc..4d0be018a4 100644 --- a/slither/detectors/variables/uninitialized_storage_variables.py +++ b/slither/detectors/variables/uninitialized_storage_variables.py @@ -4,6 +4,7 @@ Recursively explore the CFG to only report uninitialized storage variables that are written before being read """ + from typing import List from slither.core.cfg.node import Node @@ -111,7 +112,7 @@ def _detect(self) -> List[Output]: function.entry_point.context[self.key] = uninitialized_storage_variables self._detect_uninitialized(function, function.entry_point, []) - for (function, uninitialized_storage_variable) in self.results: + for function, uninitialized_storage_variable in self.results: info = [ uninitialized_storage_variable, " is a storage variable never initialized\n", diff --git a/slither/detectors/variables/unused_state_variables.py b/slither/detectors/variables/unused_state_variables.py index 0fb068fda4..c9db644ec5 100644 --- a/slither/detectors/variables/unused_state_variables.py +++ b/slither/detectors/variables/unused_state_variables.py @@ -1,6 +1,7 @@ """ Module detecting unused state variables """ + from typing import List, Optional, Dict from slither.core.compilation_unit import SlitherCompilationUnit diff --git a/slither/formatters/naming_convention/naming_convention.py b/slither/formatters/naming_convention/naming_convention.py index 8b3c40df4a..d322e6ec4a 100644 --- a/slither/formatters/naming_convention/naming_convention.py +++ b/slither/formatters/naming_convention/naming_convention.py @@ -132,7 +132,7 @@ def custom_format(compilation_unit: SlitherCompilationUnit, result: Dict) -> Non def _name_already_use(slither: SlitherCompilationUnit, name: str) -> bool: # Do not convert to a name used somewhere else - if not KEY in slither.context: + if KEY not in slither.context: all_names: Set[str] = set() for contract in slither.contracts_derived: all_names = all_names.union({st.name for st in contract.structures}) @@ -624,7 +624,7 @@ def _explore_irs( full_txt_start:full_txt_end ] - if not target.name.encode("utf8") in full_txt: + if target.name.encode("utf8") not in full_txt: raise FormatError(f"{target} not found in {full_txt} ({source_mapping}") old_str = target.name.encode("utf8") diff --git a/slither/formatters/utils/patches.py b/slither/formatters/utils/patches.py index 9eb8834059..16b9c42cda 100644 --- a/slither/formatters/utils/patches.py +++ b/slither/formatters/utils/patches.py @@ -5,6 +5,7 @@ from slither.core.compilation_unit import SlitherCompilationUnit + # pylint: disable=too-many-arguments def create_patch( result: Dict, diff --git a/slither/printers/all_printers.py b/slither/printers/all_printers.py index 3edd5325b6..7e9f414b47 100644 --- a/slither/printers/all_printers.py +++ b/slither/printers/all_printers.py @@ -24,3 +24,31 @@ from .summary.declaration import Declaration from .functions.dominator import Dominator from .summary.martin import Martin + +__all__ = [ + "FunctionSummary", + "ContractSummary", + "LocPrinter", + "PrinterInheritance", + "PrinterInheritanceGraph", + "PrinterCallGraph", + "PrinterWrittenVariablesAndAuthorization", + "PrinterSlithIR", + "PrinterSlithIRSSA", + "PrinterHumanSummary", + "CK", + "Halstead", + "CFG", + "FunctionIds", + "VariableOrder", + "DataDependency", + "Modifiers", + "RequireOrAssert", + "ConstructorPrinter", + "Echidna", + "PrinterEVM", + "PrinterWhenNotPaused", + "Declaration", + "Dominator", + "Martin", +] diff --git a/slither/printers/call/call_graph.py b/slither/printers/call/call_graph.py index 38225e6d7a..bf969138a4 100644 --- a/slither/printers/call/call_graph.py +++ b/slither/printers/call/call_graph.py @@ -5,6 +5,7 @@ what are the contracts/functions called. The output is a dot file named filename.dot """ + from collections import defaultdict from typing import Optional, Union, Dict, Set, Tuple, Sequence @@ -119,7 +120,7 @@ def _process_external_call( ) -> None: external_contract, external_function = external_call - if not external_contract in all_contracts: + if external_contract not in all_contracts: return # add variable as node to respective contract diff --git a/slither/printers/functions/authorization.py b/slither/printers/functions/authorization.py index 32efeaabeb..a950d11cd2 100644 --- a/slither/printers/functions/authorization.py +++ b/slither/printers/functions/authorization.py @@ -1,6 +1,7 @@ """ Module printing summary of the contract """ + from typing import List from slither.printers.abstract_printer import AbstractPrinter diff --git a/slither/printers/inheritance/inheritance.py b/slither/printers/inheritance/inheritance.py index 4ef961a5a7..58548bba9e 100644 --- a/slither/printers/inheritance/inheritance.py +++ b/slither/printers/inheritance/inheritance.py @@ -62,7 +62,7 @@ def output(self, filename): result["base_to_child"][base.name] = {"immediate": [], "not_immediate": []} if children: immediate = [child for child in children if base in child.immediate_inheritance] - not_immediate = [child for child in children if not child in immediate] + not_immediate = [child for child in children if child not in immediate] info += " -> " + blue(", ".join(map(str, immediate))) + "\n" result["base_to_child"][base.name]["immediate"] = list(map(str, immediate)) diff --git a/slither/printers/summary/ck.py b/slither/printers/summary/ck.py index 78da23756b..d72f27c8bc 100644 --- a/slither/printers/summary/ck.py +++ b/slither/printers/summary/ck.py @@ -30,6 +30,7 @@ - Ext calls: total number of external calls """ + from slither.printers.abstract_printer import AbstractPrinter from slither.utils.ck import CKMetrics from slither.utils.output import Output diff --git a/slither/printers/summary/constructor_calls.py b/slither/printers/summary/constructor_calls.py index 789811c360..c8a1207a12 100644 --- a/slither/printers/summary/constructor_calls.py +++ b/slither/printers/summary/constructor_calls.py @@ -1,6 +1,7 @@ """ Module printing summary of the contract """ + from slither.core.declarations import Function from slither.core.source_mapping.source_mapping import Source from slither.printers.abstract_printer import AbstractPrinter diff --git a/slither/printers/summary/contract.py b/slither/printers/summary/contract.py index 3980c63fc7..299ebcb15f 100644 --- a/slither/printers/summary/contract.py +++ b/slither/printers/summary/contract.py @@ -1,6 +1,7 @@ """ Module printing summary of the contract """ + import collections from typing import Dict, List diff --git a/slither/printers/summary/data_depenency.py b/slither/printers/summary/data_depenency.py index 8646529781..6759d0ef11 100644 --- a/slither/printers/summary/data_depenency.py +++ b/slither/printers/summary/data_depenency.py @@ -1,6 +1,7 @@ """ Module printing summary of the contract """ + from typing import List from slither.core.declarations import Contract diff --git a/slither/printers/summary/evm.py b/slither/printers/summary/evm.py index b834eb6eb8..ca5e8c24d0 100644 --- a/slither/printers/summary/evm.py +++ b/slither/printers/summary/evm.py @@ -1,6 +1,7 @@ """ Module printing evm mapping of the contract """ + import logging from typing import Union, List, Dict @@ -134,12 +135,16 @@ def output(self, _filename): txt += self.build_element_node_str( function, - evm_info["mapping", contract.name] - if not function.is_constructor - else evm_info["mapping_init", contract.name], - evm_info["cfg", contract.name] - if not function.is_constructor - else evm_info["cfg_init", contract.name], + ( + evm_info["mapping", contract.name] + if not function.is_constructor + else evm_info["mapping_init", contract.name] + ), + ( + evm_info["cfg", contract.name] + if not function.is_constructor + else evm_info["cfg_init", contract.name] + ), ) for modifier in contract.modifiers: diff --git a/slither/printers/summary/function_ids.py b/slither/printers/summary/function_ids.py index ca02dd7549..8a1f2fc4fb 100644 --- a/slither/printers/summary/function_ids.py +++ b/slither/printers/summary/function_ids.py @@ -1,6 +1,7 @@ """ Module printing summary of the contract """ + from slither.printers.abstract_printer import AbstractPrinter from slither.utils.function import get_function_id from slither.utils.myprettytable import MyPrettyTable diff --git a/slither/printers/summary/halstead.py b/slither/printers/summary/halstead.py index d3c3557db9..a1257e189f 100644 --- a/slither/printers/summary/halstead.py +++ b/slither/printers/summary/halstead.py @@ -23,6 +23,7 @@ B = (E^(2/3)) / 3000 # Number of delivered bugs """ + from slither.printers.abstract_printer import AbstractPrinter from slither.utils.halstead import HalsteadMetrics from slither.utils.output import Output diff --git a/slither/printers/summary/human_summary.py b/slither/printers/summary/human_summary.py index 314335ebf4..3a41e2ab3d 100644 --- a/slither/printers/summary/human_summary.py +++ b/slither/printers/summary/human_summary.py @@ -1,6 +1,7 @@ """ Module printing summary of the contract """ + import logging from typing import Tuple, List, Dict diff --git a/slither/printers/summary/martin.py b/slither/printers/summary/martin.py index a0f1bbfcb1..6471155b89 100644 --- a/slither/printers/summary/martin.py +++ b/slither/printers/summary/martin.py @@ -9,6 +9,7 @@ Distance from the Main Sequence (D): abs(A + I - 1) """ + from slither.printers.abstract_printer import AbstractPrinter from slither.utils.martin import MartinMetrics from slither.utils.output import Output diff --git a/slither/printers/summary/modifier_calls.py b/slither/printers/summary/modifier_calls.py index cd6c4062e3..05dc04b5e6 100644 --- a/slither/printers/summary/modifier_calls.py +++ b/slither/printers/summary/modifier_calls.py @@ -32,7 +32,7 @@ def output(self, _filename): for call in function.all_internal_calls(): if isinstance(call, Function): modifiers += call.modifiers - for (_, call) in function.all_library_calls(): + for _, call in function.all_library_calls(): if isinstance(call, Function): modifiers += call.modifiers table.add_row([function.name, sorted([m.name for m in set(modifiers)])]) diff --git a/slither/printers/summary/slithir.py b/slither/printers/summary/slithir.py index cbdb50dcc3..e9f3102e60 100644 --- a/slither/printers/summary/slithir.py +++ b/slither/printers/summary/slithir.py @@ -1,6 +1,7 @@ """ Module printing summary of the contract """ + from slither.core.declarations import Function from slither.printers.abstract_printer import AbstractPrinter diff --git a/slither/slithir/convert.py b/slither/slithir/convert.py index 7d8aa543bf..4d063a5c8a 100644 --- a/slither/slithir/convert.py +++ b/slither/slithir/convert.py @@ -351,7 +351,7 @@ def integrate_value_gas(result: List[Operation]) -> List[Operation]: variable_to_replace[ins.lvalue.name] = ins.ori.variable_left # type: ignore # Remove the call to value/gas instruction - result = [i for i in result if not i in to_remove] + result = [i for i in result if i not in to_remove] # update the real call for ins in result: @@ -1234,7 +1234,11 @@ def can_be_low_level(ir: HighLevelCall) -> bool: def convert_to_low_level( ir: HighLevelCall, -) -> Union[Send, LowLevelCall, Transfer,]: +) -> Union[ + Send, + LowLevelCall, + Transfer, +]: """ Convert to a transfer/send/or low level call The funciton assume to receive a correct IR @@ -1414,9 +1418,15 @@ def convert_to_push_set_val( ret.append(ir_assign_value) -def convert_to_push( - ir: HighLevelCall, node: "Node" -) -> List[Union[Length, Assignment, Binary, Index, InitArray,]]: +def convert_to_push(ir: HighLevelCall, node: "Node") -> List[ + Union[ + Length, + Assignment, + Binary, + Index, + InitArray, + ] +]: """ Convert a call to a series of operations to push a new value onto the array @@ -1510,7 +1520,12 @@ def look_for_library_or_top_level( str, TypeAliasTopLevel, ], -) -> Optional[Union[LibraryCall, InternalCall,]]: +) -> Optional[ + Union[ + LibraryCall, + InternalCall, + ] +]: for destination in using_for[t]: if isinstance(destination, FunctionTopLevel) and destination.name == ir.function_name: arguments = [ir.destination] + ir.arguments @@ -1558,9 +1573,12 @@ def look_for_library_or_top_level( return None -def convert_to_library_or_top_level( - ir: HighLevelCall, node: "Node", using_for -) -> Optional[Union[LibraryCall, InternalCall,]]: +def convert_to_library_or_top_level(ir: HighLevelCall, node: "Node", using_for) -> Optional[ + Union[ + LibraryCall, + InternalCall, + ] +]: t = ir.destination.type if t in using_for: new_ir = look_for_library_or_top_level(ir, using_for, t) @@ -1890,7 +1908,7 @@ def remove_unused(result: List[Operation]) -> List[Operation]: for ins in result: if isinstance(ins, Member): - if not ins.lvalue.name in to_keep and ins != last_elem: + if ins.lvalue.name not in to_keep and ins != last_elem: to_remove.append(ins) removed = True # Remove type(X) if X is an elementary type @@ -1900,7 +1918,7 @@ def remove_unused(result: List[Operation]) -> List[Operation]: if isinstance(ins.arguments[0], ElementaryType): to_remove.append(ins) - result = [i for i in result if not i in to_remove] + result = [i for i in result if i not in to_remove] return result diff --git a/slither/slithir/operations/return_operation.py b/slither/slithir/operations/return_operation.py index 290572ebf8..0e7d1ecfbf 100644 --- a/slither/slithir/operations/return_operation.py +++ b/slither/slithir/operations/return_operation.py @@ -35,7 +35,7 @@ def __init__( # Prior Solidity 0.5 # return (0,) # was valid for returns(uint) - self._values = [v for v in values if not v is None] + self._values = [v for v in values if v is not None] self._valid_value(self._values) super().__init__() diff --git a/slither/slithir/operations/type_conversion.py b/slither/slithir/operations/type_conversion.py index 08b87ab49a..74da591f0a 100644 --- a/slither/slithir/operations/type_conversion.py +++ b/slither/slithir/operations/type_conversion.py @@ -35,7 +35,11 @@ def variable(self) -> SourceMapping: @property def type( self, - ) -> Union[TypeAlias, UserDefinedType, ElementaryType,]: + ) -> Union[ + TypeAlias, + UserDefinedType, + ElementaryType, + ]: return self._type @property diff --git a/slither/slithir/utils/ssa.py b/slither/slithir/utils/ssa.py index 5e5d87325b..1969cec3be 100644 --- a/slither/slithir/utils/ssa.py +++ b/slither/slithir/utils/ssa.py @@ -85,7 +85,7 @@ def transform_slithir_vars_to_ssa( variables = [] for node in function.nodes: for ir in node.irs_ssa: - if isinstance(ir, OperationWithLValue) and not ir.lvalue in variables: + if isinstance(ir, OperationWithLValue) and ir.lvalue not in variables: variables += [ir.lvalue] tmp_variables = [v for v in variables if isinstance(v, TemporaryVariable)] @@ -137,7 +137,7 @@ def add_ssa_ir( # We only add phi function for state variable at entry node if # The state variable is used # And if the state variables is written in another function (otherwise its stay at index 0) - for (_, variable_instance) in all_state_variables_instances.items(): + for _, variable_instance in all_state_variables_instances.items(): if is_used_later(function.entry_point, variable_instance): # rvalues are fixed in solc_parsing.declaration.function function.entry_point.add_ssa_ir(Phi(StateIRVariable(variable_instance), set())) @@ -145,13 +145,13 @@ def add_ssa_ir( add_phi_origins(function.entry_point, init_definition, {}) for node in function.nodes: - for (variable, nodes) in node.phi_origins_local_variables.values(): + for variable, nodes in node.phi_origins_local_variables.values(): if len(nodes) < 2: continue if not is_used_later(node, variable): continue node.add_ssa_ir(Phi(LocalIRVariable(variable), nodes)) - for (variable, nodes) in node.phi_origins_state_variables.values(): + for variable, nodes in node.phi_origins_state_variables.values(): if len(nodes) < 2: continue # if not is_used_later(node, variable.name, []): @@ -227,7 +227,7 @@ def generate_ssa_irs( return if node.type in [NodeType.ENDIF, NodeType.ENDLOOP] and any( - not father in visited for father in node.fathers + father not in visited for father in node.fathers ): return @@ -345,7 +345,10 @@ def last_name( LocalIRVariable, ], init_vars: Dict[str, LocalIRVariable], -) -> Union[StateIRVariable, LocalIRVariable,]: +) -> Union[ + StateIRVariable, + LocalIRVariable, +]: candidates = [] # Todo optimize by creating a variables_ssa_written attribute for ir_ssa in n.irs_ssa: @@ -399,7 +402,7 @@ def is_used_later( ): return False for son in node.sons: - if not son in explored: + if son not in explored: to_explore.add(son) return False @@ -556,7 +559,7 @@ def add_phi_origins( # For unini variable declaration if ( node.variable_declaration - and not node.variable_declaration.name in local_variables_definition + and node.variable_declaration.name not in local_variables_definition ): local_variables_definition[node.variable_declaration.name] = ( node.variable_declaration, @@ -609,7 +612,7 @@ def get( if isinstance(variable, StateVariable) and variable.canonical_name in state_variables_instances: return state_variables_instances[variable.canonical_name] if isinstance(variable, ReferenceVariable): - if not variable.index in reference_variables_instances: + if variable.index not in reference_variables_instances: new_variable = ReferenceVariableSSA(variable) if variable.points_to: new_variable.points_to = get( @@ -625,13 +628,13 @@ def get( reference_variables_instances[variable.index] = new_variable return reference_variables_instances[variable.index] if isinstance(variable, TemporaryVariable): - if not variable.index in temporary_variables_instances: + if variable.index not in temporary_variables_instances: new_variable = TemporaryVariableSSA(variable) new_variable.set_type(variable.type) temporary_variables_instances[variable.index] = new_variable return temporary_variables_instances[variable.index] if isinstance(variable, TupleVariable): - if not variable.index in tuple_variables_instances: + if variable.index not in tuple_variables_instances: new_variable = TupleVariableSSA(variable) new_variable.set_type(variable.type) tuple_variables_instances[variable.index] = new_variable diff --git a/slither/slithir/variables/reference_ssa.py b/slither/slithir/variables/reference_ssa.py index 6359b57229..07c49b9d61 100644 --- a/slither/slithir/variables/reference_ssa.py +++ b/slither/slithir/variables/reference_ssa.py @@ -3,6 +3,7 @@ It is similar to the non-SSA version of slithIR as the ReferenceVariable are in SSA form in both version """ + from typing import Union from slither.slithir.variables.reference import ReferenceVariable from slither.slithir.variables.tuple import TupleVariable diff --git a/slither/slithir/variables/temporary_ssa.py b/slither/slithir/variables/temporary_ssa.py index 0d8fb8e3cb..19ac88d6c7 100644 --- a/slither/slithir/variables/temporary_ssa.py +++ b/slither/slithir/variables/temporary_ssa.py @@ -3,6 +3,7 @@ It is similar to the non-SSA version of slithIR as the TemporaryVariable are in SSA form in both version """ + from typing import Union from slither.slithir.variables.temporary import TemporaryVariable from slither.slithir.variables.reference import ReferenceVariable diff --git a/slither/slithir/variables/tuple_ssa.py b/slither/slithir/variables/tuple_ssa.py index 881feb1d68..20e9490f6c 100644 --- a/slither/slithir/variables/tuple_ssa.py +++ b/slither/slithir/variables/tuple_ssa.py @@ -3,6 +3,7 @@ It is similar to the non-SSA version of slithIR as the TupleVariable are in SSA form in both version """ + from slither.slithir.variables.tuple import TupleVariable diff --git a/slither/solc_parsing/declarations/contract.py b/slither/solc_parsing/declarations/contract.py index 1ccdc57602..1f1a29dd67 100644 --- a/slither/solc_parsing/declarations/contract.py +++ b/slither/solc_parsing/declarations/contract.py @@ -255,7 +255,7 @@ def _parse_base_contract_info(self) -> None: # pylint: disable=too-many-branche def _parse_contract_items(self) -> None: # pylint: disable=too-many-branches - if not self.get_children() in self._data: # empty contract + if self.get_children() not in self._data: # empty contract return for item in self._data[self.get_children()]: if item[self.get_key()] == "FunctionDefinition": @@ -573,12 +573,12 @@ def _analyze_params_elements( # pylint: disable=too-many-arguments,too-many-loc } for element_parser in elements_no_params: - accessible_elements[ - element_parser.underlying_function.full_name - ] = element_parser.underlying_function - all_elements[ - element_parser.underlying_function.canonical_name - ] = element_parser.underlying_function + accessible_elements[element_parser.underlying_function.full_name] = ( + element_parser.underlying_function + ) + all_elements[element_parser.underlying_function.canonical_name] = ( + element_parser.underlying_function + ) for element in all_elements.values(): if accessible_elements[element.full_name] != all_elements[element.canonical_name]: diff --git a/slither/solc_parsing/declarations/event_contract.py b/slither/solc_parsing/declarations/event_contract.py index 6af45ba527..a8e4e97beb 100644 --- a/slither/solc_parsing/declarations/event_contract.py +++ b/slither/solc_parsing/declarations/event_contract.py @@ -1,6 +1,7 @@ """ EventContract module """ + from typing import TYPE_CHECKING, Dict from slither.core.variables.event_variable import EventVariable diff --git a/slither/solc_parsing/declarations/event_top_level.py b/slither/solc_parsing/declarations/event_top_level.py index 9b6b676c79..ea6eaf03c6 100644 --- a/slither/solc_parsing/declarations/event_top_level.py +++ b/slither/solc_parsing/declarations/event_top_level.py @@ -1,6 +1,7 @@ """ EventTopLevel module """ + from typing import TYPE_CHECKING, Dict from slither.core.declarations.event_top_level import EventTopLevel diff --git a/slither/solc_parsing/declarations/function.py b/slither/solc_parsing/declarations/function.py index 57f4b26f12..43aef779ef 100644 --- a/slither/solc_parsing/declarations/function.py +++ b/slither/solc_parsing/declarations/function.py @@ -162,9 +162,9 @@ def _add_local_variable( known_variables = [v.name for v in self._function.variables] if local_var_parser.reference_id is not None: self._variables_renamed[local_var_parser.reference_id] = local_var_parser - self._function.variables_as_dict[ - local_var_parser.underlying_variable.name - ] = local_var_parser.underlying_variable + self._function.variables_as_dict[local_var_parser.underlying_variable.name] = ( + local_var_parser.underlying_variable + ) self._local_variables_parser.append(local_var_parser) # endregion diff --git a/slither/solc_parsing/declarations/modifier.py b/slither/solc_parsing/declarations/modifier.py index dfacc87038..6950f0584b 100644 --- a/slither/solc_parsing/declarations/modifier.py +++ b/slither/solc_parsing/declarations/modifier.py @@ -1,6 +1,7 @@ """ Event module """ + from typing import Dict, TYPE_CHECKING, Union from slither.core.cfg.node import NodeType diff --git a/slither/solc_parsing/declarations/structure_contract.py b/slither/solc_parsing/declarations/structure_contract.py index c48c73c4f6..a13206276f 100644 --- a/slither/solc_parsing/declarations/structure_contract.py +++ b/slither/solc_parsing/declarations/structure_contract.py @@ -1,6 +1,7 @@ """ Structure module """ + from typing import TYPE_CHECKING, Dict from slither.core.declarations.structure import Structure diff --git a/slither/solc_parsing/declarations/structure_top_level.py b/slither/solc_parsing/declarations/structure_top_level.py index 6dcca19d49..c2039e8e4f 100644 --- a/slither/solc_parsing/declarations/structure_top_level.py +++ b/slither/solc_parsing/declarations/structure_top_level.py @@ -1,6 +1,7 @@ """ Structure module """ + from typing import TYPE_CHECKING, Dict from slither.core.compilation_unit import SlitherCompilationUnit diff --git a/slither/solc_parsing/declarations/using_for_top_level.py b/slither/solc_parsing/declarations/using_for_top_level.py index bfed3c417c..ac58fb4d6b 100644 --- a/slither/solc_parsing/declarations/using_for_top_level.py +++ b/slither/solc_parsing/declarations/using_for_top_level.py @@ -1,6 +1,7 @@ """ Using For Top Level module """ + import logging from typing import TYPE_CHECKING, Dict, Union diff --git a/slither/solc_parsing/expressions/expression_parsing.py b/slither/solc_parsing/expressions/expression_parsing.py index afa5c367b2..06f850cfea 100644 --- a/slither/solc_parsing/expressions/expression_parsing.py +++ b/slither/solc_parsing/expressions/expression_parsing.py @@ -103,6 +103,7 @@ def filter_name(value: str) -> str: ################################################################################### ################################################################################### + # pylint: disable=too-many-statements def parse_call( expression: Dict, caller_context: Union["FunctionSolc", "ContractSolc", "TopLevelVariableSolc"] diff --git a/slither/solc_parsing/expressions/find_variable.py b/slither/solc_parsing/expressions/find_variable.py index 4ea1239e52..1c94d095ca 100644 --- a/slither/solc_parsing/expressions/find_variable.py +++ b/slither/solc_parsing/expressions/find_variable.py @@ -30,7 +30,6 @@ if TYPE_CHECKING: from slither.solc_parsing.declarations.function import FunctionSolc - from slither.solc_parsing.declarations.contract import ContractSolc # pylint: disable=import-outside-toplevel,too-many-branches,too-many-locals @@ -264,7 +263,11 @@ def _find_in_contract( # pylint: disable=too-many-statements def _find_variable_init( caller_context: CallerContextExpression, -) -> Tuple[List[Contract], List["Function"], FileScope,]: +) -> Tuple[ + List[Contract], + List["Function"], + FileScope, +]: from slither.solc_parsing.declarations.contract import ContractSolc from slither.solc_parsing.declarations.function import FunctionSolc from slither.solc_parsing.declarations.structure_top_level import StructureTopLevelSolc diff --git a/slither/solc_parsing/slither_compilation_unit_solc.py b/slither/solc_parsing/slither_compilation_unit_solc.py index 36efeef33a..6114b371cb 100644 --- a/slither/solc_parsing/slither_compilation_unit_solc.py +++ b/slither/solc_parsing/slither_compilation_unit_solc.py @@ -435,11 +435,11 @@ def _parse_source_unit(self, data: Dict, filename: str) -> None: sourceUnit = len(self._compilation_unit.core.source_code) self._compilation_unit.source_units[sourceUnit] = name - if os.path.isfile(name) and not name in self._compilation_unit.core.source_code: + if os.path.isfile(name) and name not in self._compilation_unit.core.source_code: self._compilation_unit.core.add_source_code(name) else: lib_name = os.path.join("node_modules", name) - if os.path.isfile(lib_name) and not name in self._compilation_unit.core.source_code: + if os.path.isfile(lib_name) and name not in self._compilation_unit.core.source_code: self._compilation_unit.core.add_source_code(lib_name) # endregion @@ -513,7 +513,7 @@ def resolve_remapping_and_renaming(contract_parser: ContractSolc, want: str) -> missing_inheritance = i # Resolve immediate base contracts and attach references. - for (i, src) in contract_parser.baseContracts: + for i, src in contract_parser.baseContracts: if i in contract_parser.remapping: target = resolve_remapping_and_renaming(contract_parser, i) fathers.append(target) diff --git a/slither/tools/doctor/checks/paths.py b/slither/tools/doctor/checks/paths.py index d388847ef4..a3c0e7b00c 100644 --- a/slither/tools/doctor/checks/paths.py +++ b/slither/tools/doctor/checks/paths.py @@ -22,7 +22,7 @@ def path_is_relative_to(path: Path, relative_to: Path) -> bool: if len(path_parts) < len(relative_to_parts): return False - for (a, b) in zip(path_parts, relative_to_parts): + for a, b in zip(path_parts, relative_to_parts): if a != b: return False diff --git a/slither/tools/erc_conformance/erc/ercs.py b/slither/tools/erc_conformance/erc/ercs.py index a6b9050ae9..d3c96e23bb 100644 --- a/slither/tools/erc_conformance/erc/ercs.py +++ b/slither/tools/erc_conformance/erc/ercs.py @@ -29,7 +29,7 @@ def _check_signature(erc_function: ERC, contract: Contract, ret: Dict) -> None: # The check on state variable is needed until we have a better API to handle state variable getters state_variable_as_function = contract.get_state_variable_from_name(name) - if not state_variable_as_function or not state_variable_as_function.visibility in [ + if not state_variable_as_function or state_variable_as_function.visibility not in [ "public", "external", ]: diff --git a/slither/tools/flattening/flattening.py b/slither/tools/flattening/flattening.py index 9cb2abc3f1..ded8d7197c 100644 --- a/slither/tools/flattening/flattening.py +++ b/slither/tools/flattening/flattening.py @@ -168,9 +168,11 @@ def _get_source_code( to_patch.append( Patch( attributes_start + regex.span()[0] + 1, - "external_to_internal" - if visibility == "external" - else "public_to_internal", + ( + "external_to_internal" + if visibility == "external" + else "public_to_internal" + ), ) ) else: @@ -327,7 +329,7 @@ def _export_list_used_contracts( # pylint: disable=too-many-branches for f in contract.functions_declared: for ir in f.slithir_operations: if isinstance(ir, NewContract): - if ir.contract_created != contract and not ir.contract_created in exported: + if ir.contract_created != contract and ir.contract_created not in exported: self._export_list_used_contracts( ir.contract_created, exported, list_contract, list_top_level ) diff --git a/slither/tools/mutator/mutators/AOR.py b/slither/tools/mutator/mutators/AOR.py index 0bf0fb2a29..91a32b187a 100644 --- a/slither/tools/mutator/mutators/AOR.py +++ b/slither/tools/mutator/mutators/AOR.py @@ -39,7 +39,7 @@ def _mutate(self) -> Dict: stop = start + node.source_mapping.length old_str = self.in_file_str[start:stop] line_no = node.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: # Replace the expression with true new_str = f"{old_str.split(ir.type.value)[0]}{op.value}{old_str.split(ir.type.value)[1]}" create_patch_with_line( diff --git a/slither/tools/mutator/mutators/ASOR.py b/slither/tools/mutator/mutators/ASOR.py index 2ff403b386..6660084bf3 100644 --- a/slither/tools/mutator/mutators/ASOR.py +++ b/slither/tools/mutator/mutators/ASOR.py @@ -50,7 +50,7 @@ def _mutate(self) -> Dict: stop = start + node.source_mapping.length old_str = self.in_file_str[start:stop] line_no = node.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: # Replace the expression with true new_str = f"{old_str.split(str(ir.expression.type))[0]}{op}{old_str.split(str(ir.expression.type))[1]}" create_patch_with_line( diff --git a/slither/tools/mutator/mutators/BOR.py b/slither/tools/mutator/mutators/BOR.py index a8720a4b63..8949cfb901 100644 --- a/slither/tools/mutator/mutators/BOR.py +++ b/slither/tools/mutator/mutators/BOR.py @@ -33,7 +33,7 @@ def _mutate(self) -> Dict: stop = start + node.source_mapping.length old_str = self.in_file_str[start:stop] line_no = node.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: # Replace the expression with true new_str = f"{old_str.split(ir.type.value)[0]}{op.value}{old_str.split(ir.type.value)[1]}" create_patch_with_line( diff --git a/slither/tools/mutator/mutators/CR.py b/slither/tools/mutator/mutators/CR.py index ebf93bf18a..11b57081ff 100644 --- a/slither/tools/mutator/mutators/CR.py +++ b/slither/tools/mutator/mutators/CR.py @@ -25,7 +25,7 @@ def _mutate(self) -> Dict: stop = start + node.source_mapping.length old_str = self.in_file_str[start:stop] line_no = node.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: new_str = "//" + old_str create_patch_with_line( result, diff --git a/slither/tools/mutator/mutators/FHR.py b/slither/tools/mutator/mutators/FHR.py index 028c1916cd..f9298862ff 100644 --- a/slither/tools/mutator/mutators/FHR.py +++ b/slither/tools/mutator/mutators/FHR.py @@ -24,7 +24,7 @@ def _mutate(self) -> Dict: stop = start + function.source_mapping.content.find("{") old_str = self.in_file_str[start:stop] line_no = function.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: for value in function_header_replacements: left_value = value.split(" ==> ", maxsplit=1)[0] right_value = value.split(" ==> ")[1] diff --git a/slither/tools/mutator/mutators/LIR.py b/slither/tools/mutator/mutators/LIR.py index cc58cbae16..7c138c67d6 100644 --- a/slither/tools/mutator/mutators/LIR.py +++ b/slither/tools/mutator/mutators/LIR.py @@ -38,7 +38,7 @@ def _mutate(self) -> Dict: # pylint: disable=too-many-branches stop = start + variable.source_mapping.length old_str = self.in_file_str[start:stop] line_no = variable.node_initialization.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: for value in literal_replacements: old_value = old_str[old_str.find("=") + 1 :].strip() if old_value != value: @@ -69,7 +69,7 @@ def _mutate(self) -> Dict: # pylint: disable=too-many-branches stop = start + variable.source_mapping.length old_str = self.in_file_str[start:stop] line_no = variable.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: for new_value in literal_replacements: old_value = old_str[old_str.find("=") + 1 :].strip() if old_value != new_value: diff --git a/slither/tools/mutator/mutators/LOR.py b/slither/tools/mutator/mutators/LOR.py index 2d1535b1aa..6a484f76b3 100644 --- a/slither/tools/mutator/mutators/LOR.py +++ b/slither/tools/mutator/mutators/LOR.py @@ -31,7 +31,7 @@ def _mutate(self) -> Dict: stop = start + node.source_mapping.length old_str = self.in_file_str[start:stop] line_no = node.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: # Replace the expression with true new_str = f"{old_str.split(ir.type.value)[0]} {op.value} {old_str.split(ir.type.value)[1]}" create_patch_with_line( diff --git a/slither/tools/mutator/mutators/MIA.py b/slither/tools/mutator/mutators/MIA.py index f29569f63e..ecb0dd01c6 100644 --- a/slither/tools/mutator/mutators/MIA.py +++ b/slither/tools/mutator/mutators/MIA.py @@ -19,7 +19,7 @@ def _mutate(self) -> Dict: stop = start + node.expression.source_mapping.length old_str = self.in_file_str[start:stop] line_no = node.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: # Replace the expression with true and false for value in ["true", "false"]: new_str = value diff --git a/slither/tools/mutator/mutators/MVIE.py b/slither/tools/mutator/mutators/MVIE.py index ce51792ffc..098fc8ca8a 100644 --- a/slither/tools/mutator/mutators/MVIE.py +++ b/slither/tools/mutator/mutators/MVIE.py @@ -27,7 +27,7 @@ def _mutate(self) -> Dict: old_str = self.in_file_str[start:stop] new_str = old_str[: old_str.find("=")] line_no = variable.node_initialization.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: create_patch_with_line( result, self.in_file, @@ -47,7 +47,7 @@ def _mutate(self) -> Dict: old_str = self.in_file_str[start:stop] new_str = old_str[: old_str.find("=")] line_no = variable.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: create_patch_with_line( result, self.in_file, diff --git a/slither/tools/mutator/mutators/MVIV.py b/slither/tools/mutator/mutators/MVIV.py index f9e51c5533..3c3cc694ce 100644 --- a/slither/tools/mutator/mutators/MVIV.py +++ b/slither/tools/mutator/mutators/MVIV.py @@ -27,7 +27,7 @@ def _mutate(self) -> Dict: old_str = self.in_file_str[start:stop] new_str = old_str[: old_str.find("=")] line_no = variable.node_initialization.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: create_patch_with_line( result, self.in_file, @@ -46,7 +46,7 @@ def _mutate(self) -> Dict: old_str = self.in_file_str[start:stop] new_str = old_str[: old_str.find("=")] line_no = variable.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: create_patch_with_line( result, self.in_file, diff --git a/slither/tools/mutator/mutators/MWA.py b/slither/tools/mutator/mutators/MWA.py index 9682f10caf..e2d9f77646 100644 --- a/slither/tools/mutator/mutators/MWA.py +++ b/slither/tools/mutator/mutators/MWA.py @@ -20,7 +20,7 @@ def _mutate(self) -> Dict: stop = start + node.source_mapping.length old_str = self.in_file_str[start:stop] line_no = node.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: if not isinstance(node.expression, UnaryOperation): new_str = str(UnaryOperationType.BANG) + "(" + old_str + ")" create_patch_with_line( diff --git a/slither/tools/mutator/mutators/ROR.py b/slither/tools/mutator/mutators/ROR.py index 9daae0663f..8123ec05b8 100644 --- a/slither/tools/mutator/mutators/ROR.py +++ b/slither/tools/mutator/mutators/ROR.py @@ -38,7 +38,7 @@ def _mutate(self) -> Dict: stop = start + ir.expression.source_mapping.length old_str = self.in_file_str[start:stop] line_no = node.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: # Replace the expression with true new_str = f"{old_str.split(ir.type.value)[0]} {op.value} {old_str.split(ir.type.value)[1]}" create_patch_with_line( diff --git a/slither/tools/mutator/mutators/RR.py b/slither/tools/mutator/mutators/RR.py index ba76d657f8..3bb6dbc4b9 100644 --- a/slither/tools/mutator/mutators/RR.py +++ b/slither/tools/mutator/mutators/RR.py @@ -23,7 +23,7 @@ def _mutate(self) -> Dict: stop = start + node.source_mapping.length old_str = self.in_file_str[start:stop] line_no = node.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: if not old_str.lstrip().startswith("revert"): new_str = "revert()" create_patch_with_line( diff --git a/slither/tools/mutator/mutators/SBR.py b/slither/tools/mutator/mutators/SBR.py index efbda48774..9b945a8877 100644 --- a/slither/tools/mutator/mutators/SBR.py +++ b/slither/tools/mutator/mutators/SBR.py @@ -66,7 +66,7 @@ def _mutate(self) -> Dict: stop = start + node.source_mapping.length old_str = self.in_file_str[start:stop] line_no = node.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: for value in solidity_rules: left_value = value.split(" ==> ", maxsplit=1)[0] right_value = value.split(" ==> ")[1] @@ -91,7 +91,7 @@ def _mutate(self) -> Dict: stop = start + node.source_mapping.length old_str = self.in_file_str[start:stop] line_no = node.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: for value in solidity_rules: left_value = value.split(" ==> ", maxsplit=1)[0] right_value = value.split(" ==> ")[1] diff --git a/slither/tools/mutator/mutators/UOR.py b/slither/tools/mutator/mutators/UOR.py index f427c2fbf6..04e4030aee 100644 --- a/slither/tools/mutator/mutators/UOR.py +++ b/slither/tools/mutator/mutators/UOR.py @@ -31,7 +31,7 @@ def _mutate(self) -> Dict: stop = start + node.source_mapping.length old_str = self.in_file_str[start:stop] line_no = node.source_mapping.lines - if not line_no[0] in self.dont_mutate_line: + if line_no[0] not in self.dont_mutate_line: if ( isinstance(ir_expression, UnaryOperation) and ir_expression.type in unary_operators diff --git a/slither/tools/mutator/mutators/all_mutators.py b/slither/tools/mutator/mutators/all_mutators.py index b02a2cc9b9..ca1f70683b 100644 --- a/slither/tools/mutator/mutators/all_mutators.py +++ b/slither/tools/mutator/mutators/all_mutators.py @@ -14,3 +14,21 @@ from slither.tools.mutator.mutators.ROR import ROR # severity medium from slither.tools.mutator.mutators.RR import RR # severity high from slither.tools.mutator.mutators.CR import CR # severity high + +__all__ = [ + "MVIV", + "MVIE", + "LOR", + "UOR", + "SBR", + "AOR", + "BOR", + "ASOR", + "MWA", + "LIR", + "FHR", + "MIA", + "ROR", + "RR", + "CR", +] diff --git a/slither/tools/read_storage/__init__.py b/slither/tools/read_storage/__init__.py index df9b8280d8..1d44a93b0b 100644 --- a/slither/tools/read_storage/__init__.py +++ b/slither/tools/read_storage/__init__.py @@ -1 +1,3 @@ from .read_storage import SlitherReadStorage, RpcInfo + +__all__ = ["SlitherReadStorage", "RpcInfo"] diff --git a/slither/tools/read_storage/__main__.py b/slither/tools/read_storage/__main__.py index 3baa5d351a..681e7fe35c 100644 --- a/slither/tools/read_storage/__main__.py +++ b/slither/tools/read_storage/__main__.py @@ -1,6 +1,7 @@ """ Tool to read on-chain storage from EVM """ + import json import argparse diff --git a/slither/tools/read_storage/read_storage.py b/slither/tools/read_storage/read_storage.py index 728636f2e4..0fd9251e8d 100644 --- a/slither/tools/read_storage/read_storage.py +++ b/slither/tools/read_storage/read_storage.py @@ -23,6 +23,7 @@ Literal, Identifier, BinaryOperation, + Expression, UnaryOperation, TupleExpression, TypeConversion, diff --git a/slither/tools/read_storage/utils/__init__.py b/slither/tools/read_storage/utils/__init__.py index 9a624a4c72..077d3baf06 100644 --- a/slither/tools/read_storage/utils/__init__.py +++ b/slither/tools/read_storage/utils/__init__.py @@ -1 +1,3 @@ from .utils import coerce_type, get_offset_value, get_storage_data + +__all__ = ["coerce_type", "get_offset_value", "get_storage_data"] diff --git a/slither/tools/similarity/__init__.py b/slither/tools/similarity/__init__.py index b31b92c608..acc728f128 100644 --- a/slither/tools/similarity/__init__.py +++ b/slither/tools/similarity/__init__.py @@ -1 +1,5 @@ from .model import load_model + +__all__ = [ + "load_model", +] diff --git a/slither/tools/similarity/plot.py b/slither/tools/similarity/plot.py index f11e921293..063d98823d 100644 --- a/slither/tools/similarity/plot.py +++ b/slither/tools/similarity/plot.py @@ -71,11 +71,11 @@ def plot(args: argparse.Namespace) -> None: # pylint: disable=too-many-locals logger.info("Plotting data..") plt.figure(figsize=(20, 10)) assert len(tdata) == len(fs) - for ([x, y], l) in zip(tdata, fs): + for [x, y], label in zip(tdata, fs): x = random.gauss(0, 0.01) + x y = random.gauss(0, 0.01) + y plt.scatter(x, y, c="blue") - plt.text(x - 0.001, y + 0.001, l) + plt.text(x - 0.001, y + 0.001, label) logger.info("Saving figure to plot.png..") plt.savefig("plot.png", bbox_inches="tight") diff --git a/slither/tools/slither_format/slither_format.py b/slither/tools/slither_format/slither_format.py index 3c37313fd5..8f743f4486 100644 --- a/slither/tools/slither_format/slither_format.py +++ b/slither/tools/slither_format/slither_format.py @@ -13,6 +13,7 @@ from slither.detectors.variables.could_be_immutable import CouldBeImmutable from slither.detectors.attributes.const_functions_asm import ConstantFunctionsAsm from slither.detectors.attributes.const_functions_state import ConstantFunctionsState +from slither.exceptions import SlitherError from slither.utils.colors import yellow logging.basicConfig(level=logging.INFO) @@ -59,7 +60,7 @@ def slither_format(slither: Slither, **kwargs: Dict) -> None: # pylint: disable logger.info(yellow("slither-format is in beta, carefully review each patch before merging it.")) for result in detector_results: - if not "patches" in result: + if "patches" not in result: continue one_line_description = result["description"].split("\n")[0] @@ -110,7 +111,7 @@ def choose_detectors( continue cls_detectors_to_run.append(all_detectors[d]) else: - raise Exception(f"Error: {d} is not a detector") + raise SlitherError(f"Error: {d} is not a detector") return cls_detectors_to_run diff --git a/slither/tools/upgradeability/__main__.py b/slither/tools/upgradeability/__main__.py index 56b838b9c1..43f9a8050a 100644 --- a/slither/tools/upgradeability/__main__.py +++ b/slither/tools/upgradeability/__main__.py @@ -172,7 +172,7 @@ def choose_checks( if detector in detectors: detectors_to_run.append(detectors[detector]) else: - raise Exception(f"Error: {detector} is not a detector") + raise SlitherException(f"Error: {detector} is not a detector") detectors_to_run = sorted(detectors_to_run, key=lambda x: x.IMPACT) return detectors_to_run @@ -279,6 +279,7 @@ def _checks_on_contract_and_proxy( ################################################################################### ################################################################################### + # pylint: disable=too-many-statements,too-many-branches,too-many-locals def main() -> None: json_results: Dict = { diff --git a/slither/tools/upgradeability/checks/all_checks.py b/slither/tools/upgradeability/checks/all_checks.py index 2289c38085..ed95c1727f 100644 --- a/slither/tools/upgradeability/checks/all_checks.py +++ b/slither/tools/upgradeability/checks/all_checks.py @@ -22,3 +22,23 @@ ) from slither.tools.upgradeability.checks.constant import WereConstant, BecameConstant + +__all__ = [ + "InitializablePresent", + "InitializableInherited", + "InitializableInitializer", + "MissingInitializerModifier", + "MissingCalls", + "MultipleCalls", + "InitializeTarget", + "IDCollision", + "FunctionShadowing", + "VariableWithInit", + "MissingVariable", + "DifferentVariableContractProxy", + "DifferentVariableContractNewContract", + "ExtraVariablesProxy", + "ExtraVariablesNewContract", + "WereConstant", + "BecameConstant", +] diff --git a/slither/tools/upgradeability/checks/functions_ids.py b/slither/tools/upgradeability/checks/functions_ids.py index a7a45f405a..b34dd97121 100644 --- a/slither/tools/upgradeability/checks/functions_ids.py +++ b/slither/tools/upgradeability/checks/functions_ids.py @@ -88,7 +88,7 @@ def _check(self): results = [] - for (k, _) in signatures_ids_implem.items(): + for k, _ in signatures_ids_implem.items(): if k in signatures_ids_proxy: if signatures_ids_implem[k] != signatures_ids_proxy[k]: implem_function = _get_function_or_variable( @@ -160,7 +160,7 @@ def _check(self): results = [] - for (k, _) in signatures_ids_implem.items(): + for k, _ in signatures_ids_implem.items(): if k in signatures_ids_proxy: if signatures_ids_implem[k] == signatures_ids_proxy[k]: implem_function = _get_function_or_variable( diff --git a/slither/tools/upgradeability/checks/initialization.py b/slither/tools/upgradeability/checks/initialization.py index 2055a322a7..60ca159c53 100644 --- a/slither/tools/upgradeability/checks/initialization.py +++ b/slither/tools/upgradeability/checks/initialization.py @@ -269,7 +269,7 @@ def _check(self): all_init_functions = _get_initialize_functions(self.contract) all_init_functions_called = _get_all_internal_calls(most_derived_init) + [most_derived_init] - missing_calls = [f for f in all_init_functions if not f in all_init_functions_called] + missing_calls = [f for f in all_init_functions if f not in all_init_functions_called] for f in missing_calls: info = ["Missing call to ", f, " in ", most_derived_init, ".\n"] json = self.generate_result(info) diff --git a/slither/tools/upgradeability/utils/command_line.py b/slither/tools/upgradeability/utils/command_line.py index c5767a5221..cb5ee5af85 100644 --- a/slither/tools/upgradeability/utils/command_line.py +++ b/slither/tools/upgradeability/utils/command_line.py @@ -47,7 +47,7 @@ def output_detectors(detector_classes: List[Type[AbstractCheck]]) -> None: # 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: + for argument, help_info, impact, proxy, v2 in detectors_list: table.add_row( [ str(idx), @@ -80,7 +80,7 @@ def extract_help(cls: Type[AbstractCheck]) -> str: # 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: + for argument, help_info, impact, proxy, v2 in detectors_list: print( f"{idx} | `{argument}` | {help_info} | {classification_txt[impact]} | {'X' if proxy else ''} | {'X' if v2 else ''}" ) diff --git a/slither/utils/arithmetic.py b/slither/utils/arithmetic.py index 0296231afe..48c7d58b01 100644 --- a/slither/utils/arithmetic.py +++ b/slither/utils/arithmetic.py @@ -7,6 +7,7 @@ if TYPE_CHECKING: from slither.core.declarations import Contract, Function + # pylint: disable=too-many-branches def convert_subdenomination( value: str, sub: str diff --git a/slither/utils/ck.py b/slither/utils/ck.py index ffba663ad2..2f10c6995d 100644 --- a/slither/utils/ck.py +++ b/slither/utils/ck.py @@ -30,6 +30,7 @@ - Ext calls: total number of external calls """ + from collections import OrderedDict from typing import Tuple, List, Dict from dataclasses import dataclass, field @@ -325,7 +326,7 @@ def __post_init__(self) -> None: subtitle = "" # Update each section - for (title, attr, keys) in self.SECTIONS: + for title, attr, keys in self.SECTIONS: if attr == "core": # Special handling for core section totals_enabled = False diff --git a/slither/utils/code_complexity.py b/slither/utils/code_complexity.py index aa78384999..2b05b0f9f5 100644 --- a/slither/utils/code_complexity.py +++ b/slither/utils/code_complexity.py @@ -33,14 +33,14 @@ def compute_strongly_connected_components(function: "Function") -> List[List["No visited = {n: False for n in function.nodes} assigned = {n: False for n in function.nodes} components = [] - l = [] + current_list = [] def visit(node: "Node") -> None: if not visited[node]: visited[node] = True for son in node.sons: visit(son) - l.append(node) + current_list.append(node) for n in function.nodes: visit(n) @@ -52,7 +52,7 @@ def assign(node: "Node", root: List["Node"]) -> None: for father in node.fathers: assign(father, root) - for n in reversed(l): + for n in reversed(current_list): component: List["Node"] = [] assign(n, component) if component: diff --git a/slither/utils/code_generation.py b/slither/utils/code_generation.py index 2157570101..c0b446731a 100644 --- a/slither/utils/code_generation.py +++ b/slither/utils/code_generation.py @@ -20,7 +20,6 @@ from slither.core.declarations import FunctionContract, CustomErrorContract from slither.core.variables.state_variable import StateVariable from slither.core.variables.local_variable import LocalVariable - from slither.core.variables.structure_variable import StructureVariable # pylint: disable=too-many-arguments,too-many-locals,too-many-branches @@ -287,11 +286,18 @@ def generate_custom_error_interface( error: "CustomErrorContract", unroll_structs: bool = True ) -> str: args = [ - convert_type_for_solidity_signature_to_string(arg.type).replace("(", "").replace(")", "") - if unroll_structs - else str(arg.type.type) - if isinstance(arg.type, UserDefinedType) and isinstance(arg.type.type, (Structure, Enum)) - else str(arg.type) + ( + convert_type_for_solidity_signature_to_string(arg.type) + .replace("(", "") + .replace(")", "") + if unroll_structs + else ( + str(arg.type.type) + if isinstance(arg.type, UserDefinedType) + and isinstance(arg.type.type, (Structure, Enum)) + else str(arg.type) + ) + ) for arg in error.parameters ] return f"{error.name}({', '.join(args)})" diff --git a/slither/utils/command_line.py b/slither/utils/command_line.py index f5b9ab4527..47f44a294a 100644 --- a/slither/utils/command_line.py +++ b/slither/utils/command_line.py @@ -123,7 +123,7 @@ def extract_help(cls: Union[Type[AbstractDetector], Type[AbstractPrinter]]) -> s # dont show the backdoor example if argument == "backdoor": continue - if not filter_wiki in detector.WIKI: + if filter_wiki not in detector.WIKI: continue help_info = extract_help(detector) impact = detector.IMPACT @@ -135,7 +135,7 @@ def extract_help(cls: Union[Type[AbstractDetector], Type[AbstractPrinter]]) -> s detectors_list, key=lambda element: (element[2], element[3], element[0]) ) idx = 1 - for (argument, help_info, impact, confidence) in detectors_list: + for argument, help_info, impact, confidence in detectors_list: print(f"{idx} | `{argument}` | {help_info} | {classification_txt[impact]} | {confidence}") idx = idx + 1 @@ -149,16 +149,16 @@ def extract_help(cls: Union[Type[AbstractDetector], Type[AbstractPrinter]]) -> s # 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: + for argument, help_info in printers_list: print(f"{idx} | `{argument}` | {help_info}") idx = idx + 1 -def get_level(l: str) -> int: - tab = l.count("\t") + 1 - if l.replace("\t", "").startswith(" -"): +def get_level(level: str) -> int: + tab = level.count("\t") + 1 + if level.replace("\t", "").startswith(" -"): tab = tab + 1 - if l.replace("\t", "").startswith("-"): + if level.replace("\t", "").startswith("-"): tab = tab + 1 return tab @@ -168,15 +168,15 @@ def convert_result_to_markdown(txt: str) -> str: lines = txt[0:-1].split("\n") ret = [] level = 0 - for l in lines: - next_level = get_level(l) + for line in lines: + next_level = get_level(line) prefix = "