Skip to content

Commit ac5cee7

Browse files
authored
Merge pull request #839 from crytic/dev-reference-lookup
Fix variable reference lookup
2 parents ef64a12 + 4a216ac commit ac5cee7

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

slither/solc_parsing/expressions/expression_parsing.py

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,8 @@ def find_variable(
306306
all_contracts = sl.contracts
307307
all_functions_parser = sl_parser.all_functions_and_modifiers_parser
308308

309-
# Look for all references delcaration
310-
# First look only in the context of function/contract
311-
# Then look everywhere
309+
# Only look for reference declaration in the direct contract, see comment at the end
310+
# Reference looked are split between direct and all
312311
# Because functions are copied between contracts, two functions can have the same ref
313312
# So we need to first look with respect to the direct context
314313

@@ -318,12 +317,6 @@ def find_variable(
318317
if ret:
319318
return ret
320319

321-
ret = _find_variable_from_ref_declaration(
322-
referenced_declaration, all_contracts, all_functions_parser
323-
)
324-
if ret:
325-
return ret
326-
327320
function_parser: Optional[FunctionSolc] = (
328321
caller_context if isinstance(caller_context, FunctionSolc) else None
329322
)
@@ -368,6 +361,33 @@ def find_variable(
368361
if ret:
369362
return ret
370363

364+
# Look from reference declaration in all the contracts at the end
365+
# Because they are many instances where this can't be trusted
366+
# For example in
367+
# contract A{
368+
# function _f() internal view returns(uint){
369+
# return 1;
370+
# }
371+
#
372+
# function get() public view returns(uint){
373+
# return _f();
374+
# }
375+
# }
376+
#
377+
# contract B is A{
378+
# function _f() internal view returns(uint){
379+
# return 2;
380+
# }
381+
#
382+
# }
383+
# get's AST will say that the ref declaration for _f() is A._f(), but in the context of B, its not
384+
385+
ret = _find_variable_from_ref_declaration(
386+
referenced_declaration, all_contracts, all_functions_parser
387+
)
388+
if ret:
389+
return ret
390+
371391
raise VariableNotFound("Variable not found: {} (context {})".format(var_name, caller_context))
372392

373393

0 commit comments

Comments
 (0)