slither.utils.inheritance_analysis

Detects various properties of inheritance in provided contracts.

 1"""
 2Detects various properties of inheritance in provided contracts.
 3"""
 4
 5from collections import defaultdict
 6from typing import TYPE_CHECKING, List, Dict, Set, Tuple
 7
 8if TYPE_CHECKING:
 9    from slither.core.declarations import Contract, Function
10    from slither.core.variables.state_variable import StateVariable
11
12
13def detect_c3_function_shadowing(
14    contract: "Contract",
15) -> Dict["Function", Set["Function"]]:
16    """
17    Detects and obtains functions which are indirectly shadowed via multiple inheritance by C3 linearization
18    properties, despite not directly inheriting from each other.
19
20    :param contract: The contract to check for potential C3 linearization shadowing within.
21    :return: A dict (function winner -> [shadowed functions])
22    """
23
24    targets: Dict[str, "Function"] = {
25        f.full_name: f
26        for f in contract.functions_inherited
27        if f.shadows and not f.is_constructor and not f.is_constructor_variables
28    }
29
30    collisions: Dict["Function", Set["Function"]] = defaultdict(set)
31
32    for contract_inherited in contract.immediate_inheritance:
33        for candidate in contract_inherited.functions:
34            if candidate.full_name not in targets or candidate.is_shadowed:
35                continue
36            if targets[candidate.full_name].canonical_name != candidate.canonical_name:
37                collisions[targets[candidate.full_name]].add(candidate)
38    return collisions
39
40
41def detect_state_variable_shadowing(
42    contracts: List["Contract"],
43) -> Set[Tuple["Contract", "StateVariable", "Contract", "StateVariable"]]:
44    """
45    Detects all overshadowing and overshadowed state variables in the provided contracts.
46    :param contracts: The contracts to detect shadowing within.
47    :return: Returns a set of tuples (overshadowing_contract, overshadowing_state_var, overshadowed_contract,
48    overshadowed_state_var).
49    The contract-variable pair's variable does not need to be defined in its paired contract, it may have been
50    inherited. The contracts are simply included to denote the immediate inheritance path from which the shadowed
51    variable originates.
52    """
53    results: Set[Tuple["Contract", "StateVariable", "Contract", "StateVariable"]] = set()
54    for contract in contracts:
55        variables_declared: Dict[str, "StateVariable"] = {
56            variable.name: variable for variable in contract.state_variables_declared
57        }
58        for immediate_base_contract in contract.immediate_inheritance:
59            for variable in immediate_base_contract.variables:
60                if variable.name in variables_declared:
61                    results.add(
62                        (
63                            contract,
64                            variables_declared[variable.name],
65                            immediate_base_contract,
66                            variable,
67                        )
68                    )
69    return results
14def detect_c3_function_shadowing(
15    contract: "Contract",
16) -> Dict["Function", Set["Function"]]:
17    """
18    Detects and obtains functions which are indirectly shadowed via multiple inheritance by C3 linearization
19    properties, despite not directly inheriting from each other.
20
21    :param contract: The contract to check for potential C3 linearization shadowing within.
22    :return: A dict (function winner -> [shadowed functions])
23    """
24
25    targets: Dict[str, "Function"] = {
26        f.full_name: f
27        for f in contract.functions_inherited
28        if f.shadows and not f.is_constructor and not f.is_constructor_variables
29    }
30
31    collisions: Dict["Function", Set["Function"]] = defaultdict(set)
32
33    for contract_inherited in contract.immediate_inheritance:
34        for candidate in contract_inherited.functions:
35            if candidate.full_name not in targets or candidate.is_shadowed:
36                continue
37            if targets[candidate.full_name].canonical_name != candidate.canonical_name:
38                collisions[targets[candidate.full_name]].add(candidate)
39    return collisions

Detects and obtains functions which are indirectly shadowed via multiple inheritance by C3 linearization properties, despite not directly inheriting from each other.

Parameters
  • contract: The contract to check for potential C3 linearization shadowing within.
Returns

A dict (function winner -> [shadowed functions])

42def detect_state_variable_shadowing(
43    contracts: List["Contract"],
44) -> Set[Tuple["Contract", "StateVariable", "Contract", "StateVariable"]]:
45    """
46    Detects all overshadowing and overshadowed state variables in the provided contracts.
47    :param contracts: The contracts to detect shadowing within.
48    :return: Returns a set of tuples (overshadowing_contract, overshadowing_state_var, overshadowed_contract,
49    overshadowed_state_var).
50    The contract-variable pair's variable does not need to be defined in its paired contract, it may have been
51    inherited. The contracts are simply included to denote the immediate inheritance path from which the shadowed
52    variable originates.
53    """
54    results: Set[Tuple["Contract", "StateVariable", "Contract", "StateVariable"]] = set()
55    for contract in contracts:
56        variables_declared: Dict[str, "StateVariable"] = {
57            variable.name: variable for variable in contract.state_variables_declared
58        }
59        for immediate_base_contract in contract.immediate_inheritance:
60            for variable in immediate_base_contract.variables:
61                if variable.name in variables_declared:
62                    results.add(
63                        (
64                            contract,
65                            variables_declared[variable.name],
66                            immediate_base_contract,
67                            variable,
68                        )
69                    )
70    return results

Detects all overshadowing and overshadowed state variables in the provided contracts.

Parameters
  • contracts: The contracts to detect shadowing within.
Returns

Returns a set of tuples (overshadowing_contract, overshadowing_state_var, overshadowed_contract, overshadowed_state_var). The contract-variable pair's variable does not need to be defined in its paired contract, it may have been inherited. The contracts are simply included to denote the immediate inheritance path from which the shadowed variable originates.