Skip to content

Commit

Permalink
add another test and fix pylint issues
Browse files Browse the repository at this point in the history
  • Loading branch information
0xalpharush committed Apr 7, 2024
1 parent 5a6ef0d commit 9518e16
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 32 deletions.
35 changes: 17 additions & 18 deletions slither/slither.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,32 +59,31 @@ def _update_file_scopes(sol_parser: SlitherCompilationUnitSolc):
elif refId in sol_parser.functions_by_id:
functions = sol_parser.functions_by_id[refId]
assert len(functions) == 1
function = functions[0]
scope.functions.add(function)
elif refId in sol_parser._imports_by_id:
import_directive = sol_parser._imports_by_id[refId]
scope.functions.add(functions[0])
elif refId in sol_parser.imports_by_id:
import_directive = sol_parser.imports_by_id[refId]
scope.imports.add(import_directive)
elif refId in sol_parser._top_level_variables_by_id:
top_level_variable = sol_parser._top_level_variables_by_id[refId]
elif refId in sol_parser.top_level_variables_by_id:
top_level_variable = sol_parser.top_level_variables_by_id[refId]
scope.variables[top_level_variable.name] = top_level_variable
elif refId in sol_parser._top_level_events_by_id:
top_level_event = sol_parser._top_level_events_by_id[refId]
elif refId in sol_parser.top_level_events_by_id:
top_level_event = sol_parser.top_level_events_by_id[refId]
scope.events.add(top_level_event)
elif refId in sol_parser._top_level_structures_by_id:
top_level_struct = sol_parser._top_level_structures_by_id[refId]
elif refId in sol_parser.top_level_structures_by_id:
top_level_struct = sol_parser.top_level_structures_by_id[refId]
scope.structures[top_level_struct.name] = top_level_struct
elif refId in sol_parser._top_level_type_aliases_by_id:
top_level_type_alias = sol_parser._top_level_type_aliases_by_id[refId]
elif refId in sol_parser.top_level_type_aliases_by_id:
top_level_type_alias = sol_parser.top_level_type_aliases_by_id[refId]
scope.type_aliases[top_level_type_alias.name] = top_level_type_alias
elif refId in sol_parser._top_level_enums_by_id:
top_level_enum = sol_parser._top_level_enums_by_id[refId]
elif refId in sol_parser.top_level_enums_by_id:
top_level_enum = sol_parser.top_level_enums_by_id[refId]
scope.enums[top_level_enum.name] = top_level_enum
elif refId in sol_parser._top_level_errors_by_id:
top_level_custom_error = sol_parser._top_level_errors_by_id[refId]
elif refId in sol_parser.top_level_errors_by_id:
top_level_custom_error = sol_parser.top_level_errors_by_id[refId]
scope.custom_errors.add(top_level_custom_error)
else:
logger.warning(
f"Failed to resolved name for reference id {refId} in {scope.filename}."
logger.error(
f"Failed to resolved name for reference id {refId} in {scope.filename.absolute}."
)


Expand Down
28 changes: 14 additions & 14 deletions slither/solc_parsing/slither_compilation_unit_solc.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ def __init__(self, compilation_unit: SlitherCompilationUnit) -> None:
self._contracts_by_id: Dict[int, Contract] = {}
# For top level functions, there should only be one `Function` since they can't be virtual and therefore can't be overridden.
self._functions_by_id: Dict[int, List[Function]] = defaultdict(list)
self._imports_by_id: Dict[int, Import] = {}
self._top_level_events_by_id: Dict[int, EventTopLevel] = {}
self._top_level_errors_by_id: Dict[int, EventTopLevel] = {}
self._top_level_structures_by_id: Dict[int, StructureTopLevel] = {}
self._top_level_variables_by_id: Dict[int, TopLevelVariable] = {}
self._top_level_type_aliases_by_id: Dict[int, TypeAliasTopLevel] = {}
self._top_level_enums_by_id: Dict[int, EnumTopLevel] = {}
self.imports_by_id: Dict[int, Import] = {}
self.top_level_events_by_id: Dict[int, EventTopLevel] = {}
self.top_level_errors_by_id: Dict[int, EventTopLevel] = {}
self.top_level_structures_by_id: Dict[int, StructureTopLevel] = {}
self.top_level_variables_by_id: Dict[int, TopLevelVariable] = {}
self.top_level_type_aliases_by_id: Dict[int, TypeAliasTopLevel] = {}
self.top_level_enums_by_id: Dict[int, EnumTopLevel] = {}

self._parsed = False
self._analyzed = False
Expand Down Expand Up @@ -217,7 +217,7 @@ def _parse_enum(self, top_level_data: Dict, filename: str) -> None:
self._compilation_unit.enums_top_level.append(enum)
scope.enums[name] = enum
refId = top_level_data["id"]
self._top_level_enums_by_id[refId] = enum
self.top_level_enums_by_id[refId] = enum

# pylint: disable=too-many-branches,too-many-statements,too-many-locals
def parse_top_level_items(self, data_loaded: Dict, filename: str) -> None:
Expand Down Expand Up @@ -321,7 +321,7 @@ def parse_top_level_items(self, data_loaded: Dict, filename: str) -> None:
import_directive.alias = top_level_data["attributes"]["unitAlias"]
import_directive.set_offset(top_level_data["src"], self._compilation_unit)
self._compilation_unit.import_directives.append(import_directive)
self._imports_by_id[referenceId] = import_directive
self.imports_by_id[referenceId] = import_directive

get_imported_scope = self.compilation_unit.get_scope(import_directive.filename)
scope.accessible_scopes.append(get_imported_scope)
Expand All @@ -335,7 +335,7 @@ def parse_top_level_items(self, data_loaded: Dict, filename: str) -> None:
self._compilation_unit.structures_top_level.append(st)
self._structures_top_level_parser.append(st_parser)
referenceId = top_level_data["id"]
self._top_level_structures_by_id[referenceId] = st
self.top_level_structures_by_id[referenceId] = st

elif top_level_data[self.get_key()] == "EnumDefinition":
# Note enum don't need a complex parser, so everything is directly done
Expand All @@ -350,7 +350,7 @@ def parse_top_level_items(self, data_loaded: Dict, filename: str) -> None:
self._variables_top_level_parser.append(var_parser)
scope.variables[var.name] = var
referenceId = top_level_data["id"]
self._top_level_variables_by_id[referenceId] = var
self.top_level_variables_by_id[referenceId] = var

elif top_level_data[self.get_key()] == "FunctionDefinition":
func = FunctionTopLevel(self._compilation_unit, scope)
Expand All @@ -371,7 +371,7 @@ def parse_top_level_items(self, data_loaded: Dict, filename: str) -> None:
self._compilation_unit.custom_errors.append(custom_error)
self._custom_error_parser.append(custom_error_parser)
referenceId = top_level_data["id"]
self._top_level_errors_by_id[referenceId] = custom_error
self.top_level_errors_by_id[referenceId] = custom_error

elif top_level_data[self.get_key()] == "UserDefinedValueTypeDefinition":
assert "name" in top_level_data
Expand All @@ -391,7 +391,7 @@ def parse_top_level_items(self, data_loaded: Dict, filename: str) -> None:
self._compilation_unit.type_aliases[alias] = type_alias
scope.type_aliases[alias] = type_alias
referenceId = top_level_data["id"]
self._top_level_type_aliases_by_id[referenceId] = type_alias
self.top_level_type_aliases_by_id[referenceId] = type_alias

elif top_level_data[self.get_key()] == "EventDefinition":
event = EventTopLevel(scope)
Expand All @@ -402,7 +402,7 @@ def parse_top_level_items(self, data_loaded: Dict, filename: str) -> None:
scope.events.add(event)
self._compilation_unit.events_top_level.append(event)
referenceId = top_level_data["id"]
self._top_level_events_by_id[referenceId] = event
self.top_level_events_by_id[referenceId] = event

else:
raise SlitherException(f"Top level {top_level_data[self.get_key()]} not supported")
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/solc_parsing/test_ast_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ def make_version(minor: int, patch_min: int, patch_max: int) -> List[str]:
Test("event-top-level.sol", ["0.8.22"]),
Test("solidity-0.8.24.sol", ["0.8.24"], solc_args="--evm-version cancun"),
Test("scope/inherited_function_scope.sol", ["0.8.24"]),
Test("using_for_global_user_defined_operator_1.sol", ["0.8.24"]),
]
# create the output folder if needed
try:
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"BalanceDeltaLibrary": {
"amount0(BalanceDelta)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: INLINE ASM 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n2->3;\n3[label=\"Node Type: END INLINE ASM 3\n\"];\n3->4;\n4[label=\"Node Type: RETURN 4\n\"];\n}\n",
"amount1(BalanceDelta)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: INLINE ASM 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n2->3;\n3[label=\"Node Type: END INLINE ASM 3\n\"];\n3->4;\n4[label=\"Node Type: RETURN 4\n\"];\n}\n"
},
"X": {
"get(BalanceDelta)": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n1->2;\n2[label=\"Node Type: NEW VARIABLE 2\n\"];\n}\n"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

type BalanceDelta is int256;

using {add as +, sub as -, eq as ==} for BalanceDelta global;
using BalanceDeltaLibrary for BalanceDelta global;

function toBalanceDelta(int128 _amount0, int128 _amount1) pure returns (BalanceDelta balanceDelta) {
/// @solidity memory-safe-assembly
assembly {
balanceDelta :=
or(shl(128, _amount0), and(0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff, _amount1))
}
}

function add(BalanceDelta a, BalanceDelta b) pure returns (BalanceDelta) {
return toBalanceDelta(a.amount0() + b.amount0(), a.amount1() + b.amount1());
}

function sub(BalanceDelta a, BalanceDelta b) pure returns (BalanceDelta) {
return toBalanceDelta(a.amount0() - b.amount0(), a.amount1() - b.amount1());
}

function eq(BalanceDelta a, BalanceDelta b) pure returns (bool) {
return a.amount0() == b.amount0() && a.amount1() == b.amount1();
}

library BalanceDeltaLibrary {
function amount0(BalanceDelta balanceDelta) internal pure returns (int128 _amount0) {
/// @solidity memory-safe-assembly
assembly {
_amount0 := shr(128, balanceDelta)
}
}

function amount1(BalanceDelta balanceDelta) internal pure returns (int128 _amount1) {
/// @solidity memory-safe-assembly
assembly {
_amount1 := balanceDelta
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

import {BalanceDelta} from "./using_for_global_user_defined_operator.sol";
contract X {

function get(BalanceDelta delta) external {
int128 amount0 = delta.amount0();
int128 amount1 = delta.amount1();
}
}

0 comments on commit 9518e16

Please sign in to comment.