@ -10,7 +10,9 @@ from slither.core.declarations import (
SolidityFunction ,
SolidityFunction ,
Contract ,
Contract ,
)
)
from slither . core . declarations . function import FunctionLanguage
from slither . core . declarations . function_contract import FunctionContract
from slither . core . declarations . function_contract import FunctionContract
from slither . core . declarations . function_top_level import FunctionTopLevel
from slither . core . expressions import (
from slither . core . expressions import (
Literal ,
Literal ,
AssignmentOperation ,
AssignmentOperation ,
@ -353,7 +355,13 @@ def convert_yul_block(
def convert_yul_function_definition (
def convert_yul_function_definition (
root : YulScope , parent : YulNode , ast : Dict , node_scope : Union [ Function , Scope ]
root : YulScope , parent : YulNode , ast : Dict , node_scope : Union [ Function , Scope ]
) - > YulNode :
) - > YulNode :
func = FunctionContract ( root . compilation_unit )
top_node_scope = node_scope
while not isinstance ( top_node_scope , Function ) :
top_node_scope = top_node_scope . father
assert isinstance ( top_node_scope , ( FunctionTopLevel , FunctionContract ) )
func = type ( top_node_scope ) ( root . compilation_unit )
func . function_language = FunctionLanguage . Yul
yul_function = YulFunction ( func , root , ast , node_scope )
yul_function = YulFunction ( func , root , ast , node_scope )
root . contract . add_function ( func )
root . contract . add_function ( func )
@ -707,6 +715,15 @@ def parse_yul_function_call(root: YulScope, node: YulNode, ast: Dict) -> Optiona
raise SlitherException ( f " unexpected function call target type { str ( type ( ident . value ) ) } " )
raise SlitherException ( f " unexpected function call target type { str ( type ( ident . value ) ) } " )
def _check_for_state_variable_name ( root : YulScope , potential_name : str ) - > Optional [ Identifier ] :
root_function = root . function
if isinstance ( root_function , FunctionContract ) :
var = root_function . contract . get_state_variable_from_name ( potential_name )
if var :
return Identifier ( var )
return None
def parse_yul_identifier ( root : YulScope , _node : YulNode , ast : Dict ) - > Optional [ Expression ] :
def parse_yul_identifier ( root : YulScope , _node : YulNode , ast : Dict ) - > Optional [ Expression ] :
name = ast [ " name " ]
name = ast [ " name " ]
@ -739,17 +756,17 @@ def parse_yul_identifier(root: YulScope, _node: YulNode, ast: Dict) -> Optional[
# check for magic suffixes
# check for magic suffixes
if name . endswith ( " _slot " ) or name . endswith ( " .slot " ) :
if name . endswith ( " _slot " ) or name . endswith ( " .slot " ) :
potential_name = name [ : - 5 ]
potential_name = name [ : - 5 ]
var = root . function . contract . get_state_variable_from_name ( potential_name )
variable_found = _check_for_state_variable_name ( root , potential_name )
if var :
if variable_found :
return Identifier ( var )
return variable_found
var = root . function . get_local_variable_from_name ( potential_name )
var = root . function . get_local_variable_from_name ( potential_name )
if var and var . is_storage :
if var and var . is_storage :
return Identifier ( var )
return Identifier ( var )
if name . endswith ( " _offset " ) or name . endswith ( " .offset " ) :
if name . endswith ( " _offset " ) or name . endswith ( " .offset " ) :
potential_name = name [ : - 7 ]
potential_name = name [ : - 7 ]
var = root . function . contract . get_state_variable_from_name ( potential_name )
variable_found = _check_for_state_variable_name ( root , potential_name )
if var :
if variable_found :
return Identifier ( var )
return variable_found
raise SlitherException ( f " unresolved reference to identifier { name } " )
raise SlitherException ( f " unresolved reference to identifier { name } " )