slither.core.compilation_unit

  1import math
  2from enum import Enum
  3from typing import Optional, Dict, List, Set, Union, TYPE_CHECKING, Tuple
  4
  5from crytic_compile import CompilationUnit, CryticCompile
  6from crytic_compile.compiler.compiler import CompilerVersion
  7from crytic_compile.utils.naming import Filename
  8
  9from slither.core.context.context import Context
 10from slither.core.declarations import (
 11    Contract,
 12    Pragma,
 13    Import,
 14    Function,
 15    Modifier,
 16)
 17from slither.core.declarations.custom_error_top_level import CustomErrorTopLevel
 18from slither.core.declarations.enum_top_level import EnumTopLevel
 19from slither.core.declarations.event_top_level import EventTopLevel
 20from slither.core.declarations.function_top_level import FunctionTopLevel
 21from slither.core.declarations.structure_top_level import StructureTopLevel
 22from slither.core.declarations.using_for_top_level import UsingForTopLevel
 23from slither.core.scope.scope import FileScope
 24from slither.core.solidity_types.type_alias import TypeAliasTopLevel
 25from slither.core.variables.state_variable import StateVariable
 26from slither.core.variables.top_level_variable import TopLevelVariable
 27from slither.slithir.operations import InternalCall
 28from slither.slithir.variables import Constant
 29
 30if TYPE_CHECKING:
 31    from slither.core.slither_core import SlitherCore
 32
 33
 34class Language(Enum):
 35    SOLIDITY = "solidity"
 36    VYPER = "vyper"
 37
 38    @staticmethod
 39    def from_str(label: str):
 40        if label == "solc":
 41            return Language.SOLIDITY
 42        if label == "vyper":
 43            return Language.VYPER
 44
 45        raise ValueError(f"Unknown language: {label}")
 46
 47
 48# pylint: disable=too-many-instance-attributes,too-many-public-methods
 49class SlitherCompilationUnit(Context):
 50    def __init__(self, core: "SlitherCore", crytic_compilation_unit: CompilationUnit) -> None:
 51        super().__init__()
 52
 53        self._core = core
 54        self._crytic_compile_compilation_unit = crytic_compilation_unit
 55        self._language = Language.from_str(crytic_compilation_unit.compiler_version.compiler)
 56
 57        # Top level object
 58        self.contracts: List[Contract] = []
 59        self._structures_top_level: List[StructureTopLevel] = []
 60        self._enums_top_level: List[EnumTopLevel] = []
 61        self._events_top_level: List[EventTopLevel] = []
 62        self._variables_top_level: List[TopLevelVariable] = []
 63        self._functions_top_level: List[FunctionTopLevel] = []
 64        self._using_for_top_level: List[UsingForTopLevel] = []
 65        self._pragma_directives: List[Pragma] = []
 66        self._import_directives: List[Import] = []
 67        self._custom_errors: List[CustomErrorTopLevel] = []
 68        self._type_aliases: Dict[str, TypeAliasTopLevel] = {}
 69
 70        self._all_functions: Set[Function] = set()
 71        self._all_modifiers: Set[Modifier] = set()
 72
 73        # Memoize
 74        self._all_state_variables: Optional[Set[StateVariable]] = None
 75
 76        self._storage_layouts: Dict[str, Dict[str, Tuple[int, int]]] = {}
 77
 78        self._contract_with_missing_inheritance: Set[Contract] = set()
 79
 80        self._source_units: Dict[int, str] = {}
 81
 82        self.counter_slithir_tuple = 0
 83        self.counter_slithir_temporary = 0
 84        self.counter_slithir_reference = 0
 85
 86        self.scopes: Dict[Filename, FileScope] = {}
 87
 88    @property
 89    def core(self) -> "SlitherCore":
 90        return self._core
 91
 92    @property
 93    def source_units(self) -> Dict[int, str]:
 94        return self._source_units
 95
 96    # endregion
 97    ###################################################################################
 98    ###################################################################################
 99    # region Compiler
100    ###################################################################################
101    ###################################################################################
102    @property
103    def language(self) -> Language:
104        return self._language
105
106    @property
107    def is_vyper(self) -> bool:
108        return self._language == Language.VYPER
109
110    @property
111    def is_solidity(self) -> bool:
112        return self._language == Language.SOLIDITY
113
114    @property
115    def compiler_version(self) -> CompilerVersion:
116        return self._crytic_compile_compilation_unit.compiler_version
117
118    @property
119    def solc_version(self) -> str:
120        # TODO: make version a non optional argument of compiler version in cc
121        return self._crytic_compile_compilation_unit.compiler_version.version  # type:ignore
122
123    @property
124    def crytic_compile_compilation_unit(self) -> CompilationUnit:
125        return self._crytic_compile_compilation_unit
126
127    @property
128    def crytic_compile(self) -> CryticCompile:
129        return self._crytic_compile_compilation_unit.crytic_compile
130
131    # endregion
132    ###################################################################################
133    ###################################################################################
134    # region Pragma attributes
135    ###################################################################################
136    ###################################################################################
137
138    @property
139    def pragma_directives(self) -> List[Pragma]:
140        """list(core.declarations.Pragma): Pragma directives."""
141        return self._pragma_directives
142
143    @property
144    def import_directives(self) -> List[Import]:
145        """list(core.declarations.Import): Import directives"""
146        return self._import_directives
147
148    # endregion
149    ###################################################################################
150    ###################################################################################
151    # region Contracts
152    ###################################################################################
153    ###################################################################################
154
155    @property
156    def contracts_derived(self) -> List[Contract]:
157        """list(Contract): List of contracts that are derived and not inherited."""
158        inheritances = [x.inheritance for x in self.contracts]
159        inheritance = [item for sublist in inheritances for item in sublist]
160        return [c for c in self.contracts if c not in inheritance]
161
162    def get_contract_from_name(self, contract_name: Union[str, Constant]) -> List[Contract]:
163        """
164            Return a list of contract from a name
165        Args:
166            contract_name (str): name of the contract
167        Returns:
168            List[Contract]
169        """
170        return [c for c in self.contracts if c.name == contract_name]
171
172    # endregion
173    ###################################################################################
174    ###################################################################################
175    # region Functions and modifiers
176    ###################################################################################
177    ###################################################################################
178
179    @property
180    def functions(self) -> List[Function]:
181        return list(self._all_functions)
182
183    def add_function(self, func: Function) -> None:
184        self._all_functions.add(func)
185
186    @property
187    def modifiers(self) -> List[Modifier]:
188        return list(self._all_modifiers)
189
190    def add_modifier(self, modif: Modifier) -> None:
191        self._all_modifiers.add(modif)
192
193    @property
194    def functions_and_modifiers(self) -> List[Function]:
195        return self.functions + list(self.modifiers)
196
197    def propagate_function_calls(self) -> None:
198        """This info is used to compute the rvalues of Phi operations in `fix_phi` and ultimately
199        is responsible for the `read` property of Phi operations which is vital to
200        propagating taints inter-procedurally
201        """
202        for f in self.functions_and_modifiers:
203            for node in f.nodes:
204                for ir in node.irs_ssa:
205                    if isinstance(ir, InternalCall):
206                        assert ir.function
207                        ir.function.add_reachable_from_node(node, ir)
208
209    # endregion
210    ###################################################################################
211    ###################################################################################
212    # region Variables
213    ###################################################################################
214    ###################################################################################
215
216    @property
217    def state_variables(self) -> List[StateVariable]:
218        if self._all_state_variables is None:
219            state_variabless = [c.state_variables for c in self.contracts]
220            state_variables = [item for sublist in state_variabless for item in sublist]
221            self._all_state_variables = set(state_variables)
222        return list(self._all_state_variables)
223
224    # endregion
225    ###################################################################################
226    ###################################################################################
227    # region Top level
228    ###################################################################################
229    ###################################################################################
230
231    @property
232    def structures_top_level(self) -> List[StructureTopLevel]:
233        return self._structures_top_level
234
235    @property
236    def enums_top_level(self) -> List[EnumTopLevel]:
237        return self._enums_top_level
238
239    @property
240    def events_top_level(self) -> List[EventTopLevel]:
241        return self._events_top_level
242
243    @property
244    def variables_top_level(self) -> List[TopLevelVariable]:
245        return self._variables_top_level
246
247    @property
248    def functions_top_level(self) -> List[FunctionTopLevel]:
249        return self._functions_top_level
250
251    @property
252    def using_for_top_level(self) -> List[UsingForTopLevel]:
253        return self._using_for_top_level
254
255    @property
256    def custom_errors(self) -> List[CustomErrorTopLevel]:
257        return self._custom_errors
258
259    @property
260    def type_aliases(self) -> Dict[str, TypeAliasTopLevel]:
261        return self._type_aliases
262
263    # endregion
264    ###################################################################################
265    ###################################################################################
266    # region Internals
267    ###################################################################################
268    ###################################################################################
269
270    @property
271    def contracts_with_missing_inheritance(self) -> Set[Contract]:
272        return self._contract_with_missing_inheritance
273
274    # endregion
275    ###################################################################################
276    ###################################################################################
277    # region Scope
278    ###################################################################################
279    ###################################################################################
280
281    def get_scope(self, filename_str: str) -> FileScope:
282        filename = self._crytic_compile_compilation_unit.crytic_compile.filename_lookup(
283            filename_str
284        )
285
286        if filename not in self.scopes:
287            self.scopes[filename] = FileScope(filename)
288
289        return self.scopes[filename]
290
291    # endregion
292    ###################################################################################
293    ###################################################################################
294    # region Storage Layouts
295    ###################################################################################
296    ###################################################################################
297
298    def compute_storage_layout(self) -> None:
299        assert self.is_solidity
300        for contract in self.contracts_derived:
301            self._storage_layouts[contract.name] = {}
302
303            slot = 0
304            offset = 0
305            for var in contract.stored_state_variables_ordered:
306                assert var.type
307                size, new_slot = var.type.storage_size
308
309                if new_slot:
310                    if offset > 0:
311                        slot += 1
312                        offset = 0
313                elif size + offset > 32:
314                    slot += 1
315                    offset = 0
316
317                self._storage_layouts[contract.name][var.canonical_name] = (
318                    slot,
319                    offset,
320                )
321                if new_slot:
322                    slot += math.ceil(size / 32)
323                else:
324                    offset += size
325
326    def storage_layout_of(self, contract: Contract, var: StateVariable) -> Tuple[int, int]:
327        return self._storage_layouts[contract.name][var.canonical_name]
328
329    # endregion
class Language(enum.Enum):
35class Language(Enum):
36    SOLIDITY = "solidity"
37    VYPER = "vyper"
38
39    @staticmethod
40    def from_str(label: str):
41        if label == "solc":
42            return Language.SOLIDITY
43        if label == "vyper":
44            return Language.VYPER
45
46        raise ValueError(f"Unknown language: {label}")

An enumeration.

SOLIDITY = <Language.SOLIDITY: 'solidity'>
VYPER = <Language.VYPER: 'vyper'>
@staticmethod
def from_str(label: str):
39    @staticmethod
40    def from_str(label: str):
41        if label == "solc":
42            return Language.SOLIDITY
43        if label == "vyper":
44            return Language.VYPER
45
46        raise ValueError(f"Unknown language: {label}")
Inherited Members
enum.Enum
name
value
class SlitherCompilationUnit(slither.core.context.context.Context):
 50class SlitherCompilationUnit(Context):
 51    def __init__(self, core: "SlitherCore", crytic_compilation_unit: CompilationUnit) -> None:
 52        super().__init__()
 53
 54        self._core = core
 55        self._crytic_compile_compilation_unit = crytic_compilation_unit
 56        self._language = Language.from_str(crytic_compilation_unit.compiler_version.compiler)
 57
 58        # Top level object
 59        self.contracts: List[Contract] = []
 60        self._structures_top_level: List[StructureTopLevel] = []
 61        self._enums_top_level: List[EnumTopLevel] = []
 62        self._events_top_level: List[EventTopLevel] = []
 63        self._variables_top_level: List[TopLevelVariable] = []
 64        self._functions_top_level: List[FunctionTopLevel] = []
 65        self._using_for_top_level: List[UsingForTopLevel] = []
 66        self._pragma_directives: List[Pragma] = []
 67        self._import_directives: List[Import] = []
 68        self._custom_errors: List[CustomErrorTopLevel] = []
 69        self._type_aliases: Dict[str, TypeAliasTopLevel] = {}
 70
 71        self._all_functions: Set[Function] = set()
 72        self._all_modifiers: Set[Modifier] = set()
 73
 74        # Memoize
 75        self._all_state_variables: Optional[Set[StateVariable]] = None
 76
 77        self._storage_layouts: Dict[str, Dict[str, Tuple[int, int]]] = {}
 78
 79        self._contract_with_missing_inheritance: Set[Contract] = set()
 80
 81        self._source_units: Dict[int, str] = {}
 82
 83        self.counter_slithir_tuple = 0
 84        self.counter_slithir_temporary = 0
 85        self.counter_slithir_reference = 0
 86
 87        self.scopes: Dict[Filename, FileScope] = {}
 88
 89    @property
 90    def core(self) -> "SlitherCore":
 91        return self._core
 92
 93    @property
 94    def source_units(self) -> Dict[int, str]:
 95        return self._source_units
 96
 97    # endregion
 98    ###################################################################################
 99    ###################################################################################
100    # region Compiler
101    ###################################################################################
102    ###################################################################################
103    @property
104    def language(self) -> Language:
105        return self._language
106
107    @property
108    def is_vyper(self) -> bool:
109        return self._language == Language.VYPER
110
111    @property
112    def is_solidity(self) -> bool:
113        return self._language == Language.SOLIDITY
114
115    @property
116    def compiler_version(self) -> CompilerVersion:
117        return self._crytic_compile_compilation_unit.compiler_version
118
119    @property
120    def solc_version(self) -> str:
121        # TODO: make version a non optional argument of compiler version in cc
122        return self._crytic_compile_compilation_unit.compiler_version.version  # type:ignore
123
124    @property
125    def crytic_compile_compilation_unit(self) -> CompilationUnit:
126        return self._crytic_compile_compilation_unit
127
128    @property
129    def crytic_compile(self) -> CryticCompile:
130        return self._crytic_compile_compilation_unit.crytic_compile
131
132    # endregion
133    ###################################################################################
134    ###################################################################################
135    # region Pragma attributes
136    ###################################################################################
137    ###################################################################################
138
139    @property
140    def pragma_directives(self) -> List[Pragma]:
141        """list(core.declarations.Pragma): Pragma directives."""
142        return self._pragma_directives
143
144    @property
145    def import_directives(self) -> List[Import]:
146        """list(core.declarations.Import): Import directives"""
147        return self._import_directives
148
149    # endregion
150    ###################################################################################
151    ###################################################################################
152    # region Contracts
153    ###################################################################################
154    ###################################################################################
155
156    @property
157    def contracts_derived(self) -> List[Contract]:
158        """list(Contract): List of contracts that are derived and not inherited."""
159        inheritances = [x.inheritance for x in self.contracts]
160        inheritance = [item for sublist in inheritances for item in sublist]
161        return [c for c in self.contracts if c not in inheritance]
162
163    def get_contract_from_name(self, contract_name: Union[str, Constant]) -> List[Contract]:
164        """
165            Return a list of contract from a name
166        Args:
167            contract_name (str): name of the contract
168        Returns:
169            List[Contract]
170        """
171        return [c for c in self.contracts if c.name == contract_name]
172
173    # endregion
174    ###################################################################################
175    ###################################################################################
176    # region Functions and modifiers
177    ###################################################################################
178    ###################################################################################
179
180    @property
181    def functions(self) -> List[Function]:
182        return list(self._all_functions)
183
184    def add_function(self, func: Function) -> None:
185        self._all_functions.add(func)
186
187    @property
188    def modifiers(self) -> List[Modifier]:
189        return list(self._all_modifiers)
190
191    def add_modifier(self, modif: Modifier) -> None:
192        self._all_modifiers.add(modif)
193
194    @property
195    def functions_and_modifiers(self) -> List[Function]:
196        return self.functions + list(self.modifiers)
197
198    def propagate_function_calls(self) -> None:
199        """This info is used to compute the rvalues of Phi operations in `fix_phi` and ultimately
200        is responsible for the `read` property of Phi operations which is vital to
201        propagating taints inter-procedurally
202        """
203        for f in self.functions_and_modifiers:
204            for node in f.nodes:
205                for ir in node.irs_ssa:
206                    if isinstance(ir, InternalCall):
207                        assert ir.function
208                        ir.function.add_reachable_from_node(node, ir)
209
210    # endregion
211    ###################################################################################
212    ###################################################################################
213    # region Variables
214    ###################################################################################
215    ###################################################################################
216
217    @property
218    def state_variables(self) -> List[StateVariable]:
219        if self._all_state_variables is None:
220            state_variabless = [c.state_variables for c in self.contracts]
221            state_variables = [item for sublist in state_variabless for item in sublist]
222            self._all_state_variables = set(state_variables)
223        return list(self._all_state_variables)
224
225    # endregion
226    ###################################################################################
227    ###################################################################################
228    # region Top level
229    ###################################################################################
230    ###################################################################################
231
232    @property
233    def structures_top_level(self) -> List[StructureTopLevel]:
234        return self._structures_top_level
235
236    @property
237    def enums_top_level(self) -> List[EnumTopLevel]:
238        return self._enums_top_level
239
240    @property
241    def events_top_level(self) -> List[EventTopLevel]:
242        return self._events_top_level
243
244    @property
245    def variables_top_level(self) -> List[TopLevelVariable]:
246        return self._variables_top_level
247
248    @property
249    def functions_top_level(self) -> List[FunctionTopLevel]:
250        return self._functions_top_level
251
252    @property
253    def using_for_top_level(self) -> List[UsingForTopLevel]:
254        return self._using_for_top_level
255
256    @property
257    def custom_errors(self) -> List[CustomErrorTopLevel]:
258        return self._custom_errors
259
260    @property
261    def type_aliases(self) -> Dict[str, TypeAliasTopLevel]:
262        return self._type_aliases
263
264    # endregion
265    ###################################################################################
266    ###################################################################################
267    # region Internals
268    ###################################################################################
269    ###################################################################################
270
271    @property
272    def contracts_with_missing_inheritance(self) -> Set[Contract]:
273        return self._contract_with_missing_inheritance
274
275    # endregion
276    ###################################################################################
277    ###################################################################################
278    # region Scope
279    ###################################################################################
280    ###################################################################################
281
282    def get_scope(self, filename_str: str) -> FileScope:
283        filename = self._crytic_compile_compilation_unit.crytic_compile.filename_lookup(
284            filename_str
285        )
286
287        if filename not in self.scopes:
288            self.scopes[filename] = FileScope(filename)
289
290        return self.scopes[filename]
291
292    # endregion
293    ###################################################################################
294    ###################################################################################
295    # region Storage Layouts
296    ###################################################################################
297    ###################################################################################
298
299    def compute_storage_layout(self) -> None:
300        assert self.is_solidity
301        for contract in self.contracts_derived:
302            self._storage_layouts[contract.name] = {}
303
304            slot = 0
305            offset = 0
306            for var in contract.stored_state_variables_ordered:
307                assert var.type
308                size, new_slot = var.type.storage_size
309
310                if new_slot:
311                    if offset > 0:
312                        slot += 1
313                        offset = 0
314                elif size + offset > 32:
315                    slot += 1
316                    offset = 0
317
318                self._storage_layouts[contract.name][var.canonical_name] = (
319                    slot,
320                    offset,
321                )
322                if new_slot:
323                    slot += math.ceil(size / 32)
324                else:
325                    offset += size
326
327    def storage_layout_of(self, contract: Contract, var: StateVariable) -> Tuple[int, int]:
328        return self._storage_layouts[contract.name][var.canonical_name]
329
330    # endregion
SlitherCompilationUnit( core: slither.core.slither_core.SlitherCore, crytic_compilation_unit: crytic_compile.compilation_unit.CompilationUnit)
51    def __init__(self, core: "SlitherCore", crytic_compilation_unit: CompilationUnit) -> None:
52        super().__init__()
53
54        self._core = core
55        self._crytic_compile_compilation_unit = crytic_compilation_unit
56        self._language = Language.from_str(crytic_compilation_unit.compiler_version.compiler)
57
58        # Top level object
59        self.contracts: List[Contract] = []
60        self._structures_top_level: List[StructureTopLevel] = []
61        self._enums_top_level: List[EnumTopLevel] = []
62        self._events_top_level: List[EventTopLevel] = []
63        self._variables_top_level: List[TopLevelVariable] = []
64        self._functions_top_level: List[FunctionTopLevel] = []
65        self._using_for_top_level: List[UsingForTopLevel] = []
66        self._pragma_directives: List[Pragma] = []
67        self._import_directives: List[Import] = []
68        self._custom_errors: List[CustomErrorTopLevel] = []
69        self._type_aliases: Dict[str, TypeAliasTopLevel] = {}
70
71        self._all_functions: Set[Function] = set()
72        self._all_modifiers: Set[Modifier] = set()
73
74        # Memoize
75        self._all_state_variables: Optional[Set[StateVariable]] = None
76
77        self._storage_layouts: Dict[str, Dict[str, Tuple[int, int]]] = {}
78
79        self._contract_with_missing_inheritance: Set[Contract] = set()
80
81        self._source_units: Dict[int, str] = {}
82
83        self.counter_slithir_tuple = 0
84        self.counter_slithir_temporary = 0
85        self.counter_slithir_reference = 0
86
87        self.scopes: Dict[Filename, FileScope] = {}
counter_slithir_tuple
counter_slithir_temporary
counter_slithir_reference
scopes: Dict[crytic_compile.utils.naming.Filename, slither.core.scope.scope.FileScope]
89    @property
90    def core(self) -> "SlitherCore":
91        return self._core
source_units: Dict[int, str]
93    @property
94    def source_units(self) -> Dict[int, str]:
95        return self._source_units
language: Language
103    @property
104    def language(self) -> Language:
105        return self._language
is_vyper: bool
107    @property
108    def is_vyper(self) -> bool:
109        return self._language == Language.VYPER
is_solidity: bool
111    @property
112    def is_solidity(self) -> bool:
113        return self._language == Language.SOLIDITY
compiler_version: crytic_compile.compiler.compiler.CompilerVersion
115    @property
116    def compiler_version(self) -> CompilerVersion:
117        return self._crytic_compile_compilation_unit.compiler_version
solc_version: str
119    @property
120    def solc_version(self) -> str:
121        # TODO: make version a non optional argument of compiler version in cc
122        return self._crytic_compile_compilation_unit.compiler_version.version  # type:ignore
crytic_compile_compilation_unit: crytic_compile.compilation_unit.CompilationUnit
124    @property
125    def crytic_compile_compilation_unit(self) -> CompilationUnit:
126        return self._crytic_compile_compilation_unit
crytic_compile: crytic_compile.crytic_compile.CryticCompile
128    @property
129    def crytic_compile(self) -> CryticCompile:
130        return self._crytic_compile_compilation_unit.crytic_compile
pragma_directives: List[slither.core.declarations.pragma_directive.Pragma]
139    @property
140    def pragma_directives(self) -> List[Pragma]:
141        """list(core.declarations.Pragma): Pragma directives."""
142        return self._pragma_directives

list(core.declarations.Pragma): Pragma directives.

import_directives: List[slither.core.declarations.import_directive.Import]
144    @property
145    def import_directives(self) -> List[Import]:
146        """list(core.declarations.Import): Import directives"""
147        return self._import_directives

list(core.declarations.Import): Import directives

contracts_derived: List[slither.core.declarations.contract.Contract]
156    @property
157    def contracts_derived(self) -> List[Contract]:
158        """list(Contract): List of contracts that are derived and not inherited."""
159        inheritances = [x.inheritance for x in self.contracts]
160        inheritance = [item for sublist in inheritances for item in sublist]
161        return [c for c in self.contracts if c not in inheritance]

list(Contract): List of contracts that are derived and not inherited.

def get_contract_from_name( self, contract_name: Union[str, slither.slithir.variables.constant.Constant]) -> List[slither.core.declarations.contract.Contract]:
163    def get_contract_from_name(self, contract_name: Union[str, Constant]) -> List[Contract]:
164        """
165            Return a list of contract from a name
166        Args:
167            contract_name (str): name of the contract
168        Returns:
169            List[Contract]
170        """
171        return [c for c in self.contracts if c.name == contract_name]

Return a list of contract from a name Args: contract_name (str): name of the contract Returns: List[Contract]

functions: List[slither.core.declarations.function.Function]
180    @property
181    def functions(self) -> List[Function]:
182        return list(self._all_functions)
def add_function(self, func: slither.core.declarations.function.Function) -> None:
184    def add_function(self, func: Function) -> None:
185        self._all_functions.add(func)
modifiers: List[slither.core.declarations.modifier.Modifier]
187    @property
188    def modifiers(self) -> List[Modifier]:
189        return list(self._all_modifiers)
def add_modifier(self, modif: slither.core.declarations.modifier.Modifier) -> None:
191    def add_modifier(self, modif: Modifier) -> None:
192        self._all_modifiers.add(modif)
functions_and_modifiers: List[slither.core.declarations.function.Function]
194    @property
195    def functions_and_modifiers(self) -> List[Function]:
196        return self.functions + list(self.modifiers)
def propagate_function_calls(self) -> None:
198    def propagate_function_calls(self) -> None:
199        """This info is used to compute the rvalues of Phi operations in `fix_phi` and ultimately
200        is responsible for the `read` property of Phi operations which is vital to
201        propagating taints inter-procedurally
202        """
203        for f in self.functions_and_modifiers:
204            for node in f.nodes:
205                for ir in node.irs_ssa:
206                    if isinstance(ir, InternalCall):
207                        assert ir.function
208                        ir.function.add_reachable_from_node(node, ir)

This info is used to compute the rvalues of Phi operations in fix_phi and ultimately is responsible for the read property of Phi operations which is vital to propagating taints inter-procedurally

state_variables: List[slither.core.variables.state_variable.StateVariable]
217    @property
218    def state_variables(self) -> List[StateVariable]:
219        if self._all_state_variables is None:
220            state_variabless = [c.state_variables for c in self.contracts]
221            state_variables = [item for sublist in state_variabless for item in sublist]
222            self._all_state_variables = set(state_variables)
223        return list(self._all_state_variables)
structures_top_level: List[slither.core.declarations.structure_top_level.StructureTopLevel]
232    @property
233    def structures_top_level(self) -> List[StructureTopLevel]:
234        return self._structures_top_level
enums_top_level: List[slither.core.declarations.enum_top_level.EnumTopLevel]
236    @property
237    def enums_top_level(self) -> List[EnumTopLevel]:
238        return self._enums_top_level
events_top_level: List[slither.core.declarations.event_top_level.EventTopLevel]
240    @property
241    def events_top_level(self) -> List[EventTopLevel]:
242        return self._events_top_level
variables_top_level: List[slither.core.variables.top_level_variable.TopLevelVariable]
244    @property
245    def variables_top_level(self) -> List[TopLevelVariable]:
246        return self._variables_top_level
functions_top_level: List[slither.core.declarations.function_top_level.FunctionTopLevel]
248    @property
249    def functions_top_level(self) -> List[FunctionTopLevel]:
250        return self._functions_top_level
252    @property
253    def using_for_top_level(self) -> List[UsingForTopLevel]:
254        return self._using_for_top_level
256    @property
257    def custom_errors(self) -> List[CustomErrorTopLevel]:
258        return self._custom_errors
type_aliases: Dict[str, slither.core.solidity_types.type_alias.TypeAliasTopLevel]
260    @property
261    def type_aliases(self) -> Dict[str, TypeAliasTopLevel]:
262        return self._type_aliases
contracts_with_missing_inheritance: Set[slither.core.declarations.contract.Contract]
271    @property
272    def contracts_with_missing_inheritance(self) -> Set[Contract]:
273        return self._contract_with_missing_inheritance
def get_scope(self, filename_str: str) -> slither.core.scope.scope.FileScope:
282    def get_scope(self, filename_str: str) -> FileScope:
283        filename = self._crytic_compile_compilation_unit.crytic_compile.filename_lookup(
284            filename_str
285        )
286
287        if filename not in self.scopes:
288            self.scopes[filename] = FileScope(filename)
289
290        return self.scopes[filename]
def compute_storage_layout(self) -> None:
299    def compute_storage_layout(self) -> None:
300        assert self.is_solidity
301        for contract in self.contracts_derived:
302            self._storage_layouts[contract.name] = {}
303
304            slot = 0
305            offset = 0
306            for var in contract.stored_state_variables_ordered:
307                assert var.type
308                size, new_slot = var.type.storage_size
309
310                if new_slot:
311                    if offset > 0:
312                        slot += 1
313                        offset = 0
314                elif size + offset > 32:
315                    slot += 1
316                    offset = 0
317
318                self._storage_layouts[contract.name][var.canonical_name] = (
319                    slot,
320                    offset,
321                )
322                if new_slot:
323                    slot += math.ceil(size / 32)
324                else:
325                    offset += size
def storage_layout_of( self, contract: slither.core.declarations.contract.Contract, var: slither.core.variables.state_variable.StateVariable) -> Tuple[int, int]:
327    def storage_layout_of(self, contract: Contract, var: StateVariable) -> Tuple[int, int]:
328        return self._storage_layouts[contract.name][var.canonical_name]