4646if TYPE_CHECKING :
4747 from slither .slithir .variables .variable import SlithIRVariable
4848 from slither .core .compilation_unit import SlitherCompilationUnit
49- from slither .utils .type_helpers import (
50- InternalCallType ,
51- HighLevelCallType ,
52- LibraryCallType ,
53- LowLevelCallType ,
54- )
5549 from slither .core .cfg .scope import Scope
5650 from slither .core .scope .scope import FileScope
5751
@@ -153,11 +147,11 @@ def __init__(
153147 self ._ssa_vars_written : List ["SlithIRVariable" ] = []
154148 self ._ssa_vars_read : List ["SlithIRVariable" ] = []
155149
156- self ._internal_calls : List [Union [ "Function" , "SolidityFunction" ]] = []
157- self ._solidity_calls : List [SolidityFunction ] = []
158- self ._high_level_calls : List ["HighLevelCallType" ] = [] # contains library calls
159- self ._library_calls : List ["LibraryCallType" ] = []
160- self ._low_level_calls : List ["LowLevelCallType" ] = []
150+ self ._internal_calls : List [InternalCall ] = [] # contains solidity calls
151+ self ._solidity_calls : List [SolidityCall ] = []
152+ self ._high_level_calls : List [Tuple [ Contract , HighLevelCall ] ] = [] # contains library calls
153+ self ._library_calls : List [LibraryCall ] = []
154+ self ._low_level_calls : List [LowLevelCall ] = []
161155 self ._external_calls_as_expressions : List [Expression ] = []
162156 self ._internal_calls_as_expressions : List [Expression ] = []
163157 self ._irs : List [Operation ] = []
@@ -226,8 +220,9 @@ def type(self, new_type: NodeType) -> None:
226220 @property
227221 def will_return (self ) -> bool :
228222 if not self .sons and self .type != NodeType .THROW :
229- if SolidityFunction ("revert()" ) not in self .solidity_calls :
230- if SolidityFunction ("revert(string)" ) not in self .solidity_calls :
223+ solidity_calls = [ir .function for ir in self .solidity_calls ]
224+ if SolidityFunction ("revert()" ) not in solidity_calls :
225+ if SolidityFunction ("revert(string)" ) not in solidity_calls :
231226 return True
232227 return False
233228
@@ -373,44 +368,38 @@ def variables_written_as_expression(self, exprs: List[Expression]) -> None:
373368 ###################################################################################
374369
375370 @property
376- def internal_calls (self ) -> List ["InternalCallType" ]:
371+ def internal_calls (self ) -> List [InternalCall ]:
377372 """
378- list(Function or SolidityFunction ): List of internal/soldiity function calls
373+ list(InternalCall ): List of IR operations with internal/solidity function calls
379374 """
380375 return list (self ._internal_calls )
381376
382377 @property
383- def solidity_calls (self ) -> List [SolidityFunction ]:
378+ def solidity_calls (self ) -> List [SolidityCall ]:
384379 """
385- list(SolidityFunction ): List of Soldity calls
380+ list(SolidityCall ): List of IR operations with solidity calls
386381 """
387382 return list (self ._solidity_calls )
388383
389384 @property
390- def high_level_calls (self ) -> List ["HighLevelCallType" ]:
385+ def high_level_calls (self ) -> List [HighLevelCall ]:
391386 """
392- list((Contract, Function|Variable)):
393- List of high level calls (external calls).
394- A variable is called in case of call to a public state variable
387+ list(HighLevelCall): List of IR operations with high level calls (external calls).
395388 Include library calls
396389 """
397390 return list (self ._high_level_calls )
398391
399392 @property
400- def library_calls (self ) -> List ["LibraryCallType" ]:
393+ def library_calls (self ) -> List [LibraryCall ]:
401394 """
402- list((Contract, Function)):
403- Include library calls
395+ list(LibraryCall): List of IR operations with library calls.
404396 """
405397 return list (self ._library_calls )
406398
407399 @property
408- def low_level_calls (self ) -> List ["LowLevelCallType" ]:
400+ def low_level_calls (self ) -> List [LowLevelCall ]:
409401 """
410- list((Variable|SolidityVariable, str)): List of low_level call
411- A low level call is defined by
412- - the variable called
413- - the name of the function (call/delegatecall/codecall)
402+ list(LowLevelCall): List of IR operations with low_level call
414403 """
415404 return list (self ._low_level_calls )
416405
@@ -529,8 +518,9 @@ def contains_require_or_assert(self) -> bool:
529518 bool: True if the node has a require or assert call
530519 """
531520 return any (
532- c .name in ["require(bool)" , "require(bool,string)" , "assert(bool)" ]
533- for c in self .internal_calls
521+ ir .function .name
522+ in ["require(bool)" , "require(bool,string)" , "require(bool,error)" , "assert(bool)" ]
523+ for ir in self .internal_calls
534524 )
535525
536526 def contains_if (self , include_loop : bool = True ) -> bool :
@@ -894,11 +884,11 @@ def _find_read_write_call(self) -> None: # pylint: disable=too-many-statements
894884 self ._vars_written .append (var )
895885
896886 if isinstance (ir , InternalCall ):
897- self ._internal_calls .append (ir . function )
887+ self ._internal_calls .append (ir )
898888 if isinstance (ir , SolidityCall ):
899889 # TODO: consider removing dependancy of solidity_call to internal_call
900- self ._solidity_calls .append (ir . function )
901- self ._internal_calls .append (ir . function )
890+ self ._solidity_calls .append (ir )
891+ self ._internal_calls .append (ir )
902892 if (
903893 isinstance (ir , SolidityCall )
904894 and ir .function == SolidityFunction ("sstore(uint256,uint256)" )
@@ -916,22 +906,22 @@ def _find_read_write_call(self) -> None: # pylint: disable=too-many-statements
916906 self ._vars_read .append (ir .arguments [0 ])
917907 if isinstance (ir , LowLevelCall ):
918908 assert isinstance (ir .destination , (Variable , SolidityVariable ))
919- self ._low_level_calls .append (( ir . destination , str ( ir . function_name . value )) )
909+ self ._low_level_calls .append (ir )
920910 elif isinstance (ir , HighLevelCall ) and not isinstance (ir , LibraryCall ):
921911 # Todo investigate this if condition
922912 # It does seem right to compare against a contract
923913 # This might need a refactoring
924914 if isinstance (ir .destination .type , Contract ):
925- self ._high_level_calls .append ((ir .destination .type , ir . function ))
915+ self ._high_level_calls .append ((ir .destination .type , ir ))
926916 elif ir .destination == SolidityVariable ("this" ):
927917 func = self .function
928918 # Can't use this in a top level function
929919 assert isinstance (func , FunctionContract )
930- self ._high_level_calls .append ((func .contract , ir . function ))
920+ self ._high_level_calls .append ((func .contract , ir ))
931921 else :
932922 try :
933923 # Todo this part needs more tests and documentation
934- self ._high_level_calls .append ((ir .destination .type .type , ir . function ))
924+ self ._high_level_calls .append ((ir .destination .type .type , ir ))
935925 except AttributeError as error :
936926 # pylint: disable=raise-missing-from
937927 raise SlitherException (
@@ -940,8 +930,8 @@ def _find_read_write_call(self) -> None: # pylint: disable=too-many-statements
940930 elif isinstance (ir , LibraryCall ):
941931 assert isinstance (ir .destination , Contract )
942932 assert isinstance (ir .function , Function )
943- self ._high_level_calls .append ((ir .destination , ir . function ))
944- self ._library_calls .append (( ir . destination , ir . function ) )
933+ self ._high_level_calls .append ((ir .destination , ir ))
934+ self ._library_calls .append (ir )
945935
946936 self ._vars_read = list (set (self ._vars_read ))
947937 self ._state_vars_read = [v for v in self ._vars_read if isinstance (v , StateVariable )]
0 commit comments