@ -31,19 +31,20 @@ from slither.utils.utils import unroll
# pylint: disable=import-outside-toplevel,too-many-instance-attributes,too-many-statements,too-many-lines
if TYPE_CHECKING :
from slither . utils . type_helpers import (
InternalCallType ,
LowLevelCallType ,
HighLevelCallType ,
LibraryCallType ,
)
from slither . core . declarations import Contract , FunctionContract
from slither . core . cfg . node import Node , NodeType
from slither . core . variables . variable import Variable
from slither . slithir . variables . variable import SlithIRVariable
from slither . slithir . variables import LocalIRVariable
from slither . core . expressions . expression import Expression
from slither . slithir . operations import Operation
from slither . slithir . operations import (
HighLevelCall ,
InternalCall ,
LibraryCall ,
LowLevelCall ,
SolidityCall ,
Operation ,
)
from slither . core . compilation_unit import SlitherCompilationUnit
from slither . core . scope . scope import FileScope
@ -149,11 +150,11 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
self . _vars_read_or_written : List [ " Variable " ] = [ ]
self . _solidity_vars_read : List [ " SolidityVariable " ] = [ ]
self . _state_vars_written : List [ " StateVariable " ] = [ ]
self . _internal_calls : List [ " InternalCallType " ] = [ ]
self . _solidity_calls : List [ " SolidityFunction " ] = [ ]
self . _low_level_calls : List [ " LowLevelCallType " ] = [ ]
self . _high_level_calls : List [ " HighLevelCallType " ] = [ ]
self . _library_calls : List [ " LibraryCallType " ] = [ ]
self . _internal_calls : List [ " InternalCall " ] = [ ]
self . _solidity_calls : List [ " SolidityCall " ] = [ ]
self . _low_level_calls : List [ " LowLevelCall " ] = [ ]
self . _high_level_calls : List [ Tuple [ " Contract " , " HighLevelCall " ] ] = [ ]
self . _library_calls : List [ " LibraryCall " ] = [ ]
self . _external_calls_as_expressions : List [ " Expression " ] = [ ]
self . _expression_vars_read : List [ " Expression " ] = [ ]
self . _expression_vars_written : List [ " Expression " ] = [ ]
@ -169,11 +170,11 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
self . _all_expressions : Optional [ List [ " Expression " ] ] = None
self . _all_slithir_operations : Optional [ List [ " Operation " ] ] = None
self . _all_internals_calls : Optional [ List [ " InternalCallType " ] ] = None
self . _all_high_level_calls : Optional [ List [ " HighLevelCallType " ] ] = None
self . _all_library_calls : Optional [ List [ " LibraryCallType " ] ] = None
self . _all_low_level_calls : Optional [ List [ " LowLevelCallType " ] ] = None
self . _all_solidity_calls : Optional [ List [ " SolidityFunction " ] ] = None
self . _all_internals_calls : Optional [ List [ " InternalCall " ] ] = None
self . _all_high_level_calls : Optional [ List [ Tuple [ " Contract " , " HighLevelCall " ] ] ] = None
self . _all_library_calls : Optional [ List [ " LibraryCall " ] ] = None
self . _all_low_level_calls : Optional [ List [ " LowLevelCall " ] ] = None
self . _all_solidity_calls : Optional [ List [ " SolidityCall " ] ] = None
self . _all_variables_read : Optional [ List [ " Variable " ] ] = None
self . _all_variables_written : Optional [ List [ " Variable " ] ] = None
self . _all_state_variables_read : Optional [ List [ " StateVariable " ] ] = None
@ -857,43 +858,42 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
###################################################################################
@property
def internal_calls ( self ) - > List [ " InternalCallType " ] :
def internal_calls ( self ) - > List [ " InternalCall " ] :
"""
list ( Function or SolidityFunction ) : List of function calls ( that does not create a transaction )
list ( InternalCall ) : List of IR operations for internal calls
"""
return list ( self . _internal_calls )
@property
def solidity_calls ( self ) - > List [ SolidityFunction ] :
def solidity_calls ( self ) - > List [ " SolidityCall " ] :
"""
list ( SolidityFunction ) : List of Soldity calls
list ( SolidityCall ) : List of IR operations for Soli dity calls
"""
return list ( self . _solidity_calls )
@property
def high_level_calls ( self ) - > List [ " HighLevelCallType " ] :
def high_level_calls ( self ) - > List [ Tuple [ " Contract " , " HighLevelCall " ] ] :
"""
list ( ( Contract , Function | Variable ) ) :
List of high level calls ( external calls ) .
list ( Tuple ( Contract , " HighLevelCall " ) ) : List of call target contract and IR of the high level call
A variable is called in case of call to a public state variable
Include library calls
"""
return list ( self . _high_level_calls )
@property
def library_calls ( self ) - > List [ " LibraryCallType " ] :
def library_calls ( self ) - > List [ " LibraryCall " ] :
"""
list ( ( Contract , Function ) ) :
list ( LibraryCall ) : List of IR operations for library calls
"""
return list ( self . _library_calls )
@property
def low_level_calls ( self ) - > List [ " LowLevelCallType " ] :
def low_level_calls ( self ) - > List [ " LowLevelCall " ] :
"""
list ( ( Variable | SolidityVariable , str ) ) : List of low_level call
list ( LowLevelCall ) : List of IR operations for low level calls
A low level call is defined by
- the variable called
- the name of the function ( call / delegatecall / codec all )
- the name of the function ( call / delegatecall / callcode )
"""
return list ( self . _low_level_calls )
@ -1121,10 +1121,14 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
values = f_new_values ( self )
explored = [ self ]
to_explore = [
c for c in self . internal_calls if isinstance ( c , Function ) and c not in explored
ir . function
for ir in self . internal_calls
if isinstance ( ir . function , Function ) and ir . function not in explored
]
to_explore + = [
c for ( _ , c ) in self . library_calls if isinstance ( c , Function ) and c not in explored
ir . function
for ir in self . library_calls
if isinstance ( ir . function , Function ) and ir . function not in explored
]
to_explore + = [ m for m in self . modifiers if m not in explored ]
@ -1138,14 +1142,18 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
values + = f_new_values ( f )
to_explore + = [
c
for c in f . internal_calls
if isinstance ( c , Function ) and c not in explored and c not in to_explore
ir . function
for ir in f . internal_calls
if isinstance ( ir . function , Function )
and ir . function not in explored
and ir . function not in to_explore
]
to_explore + = [
c
for ( _ , c ) in f . library_calls
if isinstance ( c , Function ) and c not in explored and c not in to_explore
ir . function
for ir in f . library_calls
if isinstance ( ir . function , Function )
and ir . function not in explored
and ir . function not in to_explore
]
to_explore + = [ m for m in f . modifiers if m not in explored and m not in to_explore ]
@ -1210,31 +1218,31 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
)
return self . _all_state_variables_written
def all_internal_calls ( self ) - > List [ " InternalCallType " ] :
def all_internal_calls ( self ) - > List [ " InternalCall " ] :
""" recursive version of internal_calls """
if self . _all_internals_calls is None :
self . _all_internals_calls = self . _explore_functions ( lambda x : x . internal_calls )
return self . _all_internals_calls
def all_low_level_calls ( self ) - > List [ " LowLevelCallType " ] :
def all_low_level_calls ( self ) - > List [ " LowLevelCall " ] :
""" recursive version of low_level calls """
if self . _all_low_level_calls is None :
self . _all_low_level_calls = self . _explore_functions ( lambda x : x . low_level_calls )
return self . _all_low_level_calls
def all_high_level_calls ( self ) - > List [ " HighLevelCallType " ] :
def all_high_level_calls ( self ) - > List [ Tuple [ " Contract " , " HighLevelCall " ] ] :
""" recursive version of high_level calls """
if self . _all_high_level_calls is None :
self . _all_high_level_calls = self . _explore_functions ( lambda x : x . high_level_calls )
return self . _all_high_level_calls
def all_library_calls ( self ) - > List [ " LibraryCallType " ] :
def all_library_calls ( self ) - > List [ " LibraryCall " ] :
""" recursive version of library calls """
if self . _all_library_calls is None :
self . _all_library_calls = self . _explore_functions ( lambda x : x . library_calls )
return self . _all_library_calls
def all_solidity_calls ( self ) - > List [ SolidityFunction ] :
def all_solidity_calls ( self ) - > List [ " SolidityCall " ] :
""" recursive version of solidity calls """
if self . _all_solidity_calls is None :
self . _all_solidity_calls = self . _explore_functions ( lambda x : x . solidity_calls )