diff --git a/slither/core/cfg/node.py b/slither/core/cfg/node.py index fe7d90b4a..6d2da977b 100644 --- a/slither/core/cfg/node.py +++ b/slither/core/cfg/node.py @@ -155,6 +155,7 @@ class Node(SourceMapping, ChildFunction): self._library_calls = [] self._low_level_calls = [] self._external_calls_as_expressions = [] + self._internal_calls_as_expressions = [] self._irs = [] self._irs_ssa = [] @@ -368,6 +369,13 @@ class Node(SourceMapping, ChildFunction): """ return self._external_calls_as_expressions + @property + def internal_calls_as_expressions(self): + """ + list(CallExpression): List of internal calls (that dont create a transaction) + """ + return self._internal_calls_as_expressions + @property def calls_as_expression(self): return list(self._expression_calls) diff --git a/slither/core/declarations/contract.py b/slither/core/declarations/contract.py index cbfe723f7..667a0134f 100644 --- a/slither/core/declarations/contract.py +++ b/slither/core/declarations/contract.py @@ -367,26 +367,6 @@ class Contract(ChildSlither, SourceMapping): ''' return [f for f in self.functions if f.is_writing(variable)] - def get_source_var_declaration(self, var): - """ Return the source mapping where the variable is declared - - Args: - var (str): variable name - Returns: - (dict): sourceMapping - """ - return next((x.source_mapping for x in self.variables if x.name == var)) - - def get_source_event_declaration(self, event): - """ Return the source mapping where the event is declared - - Args: - event (str): event name - Returns: - (dict): sourceMapping - """ - return next((x.source_mapping for x in self.events if x.name == event)) - def get_function_from_signature(self, function_signature): """ Return a function from a signature diff --git a/slither/core/declarations/function.py b/slither/core/declarations/function.py index 1a99f90e3..577c77b1a 100644 --- a/slither/core/declarations/function.py +++ b/slither/core/declarations/function.py @@ -39,8 +39,10 @@ class Function(ChildContract, SourceMapping): self._slithir_variables = set() # slithir Temporary and references variables (but not SSA) self._parameters = [] self._parameters_ssa = [] + self._parameters_src = None self._returns = [] self._returns_ssa = [] + self._returns_src = None self._return_values = None self._return_values_ssa = None self._vars_read = [] @@ -1071,4 +1073,4 @@ class Function(ChildContract, SourceMapping): def __str__(self): return self._name - # endregion \ No newline at end of file + # endregion diff --git a/slither/solc_parsing/cfg/node.py b/slither/solc_parsing/cfg/node.py index 56e73e32c..1775084f6 100644 --- a/slither/solc_parsing/cfg/node.py +++ b/slither/solc_parsing/cfg/node.py @@ -62,4 +62,6 @@ class NodeSolc(Node): pp = FindCalls(expression) self._expression_calls = pp.result() self._external_calls_as_expressions = [c for c in self.calls_as_expression if not isinstance(c.called, Identifier)] + self._internal_calls_as_expressions = [c for c in self.calls_as_expression if isinstance(c.called, Identifier)] + diff --git a/slither/solc_parsing/declarations/function.py b/slither/solc_parsing/declarations/function.py index d862352ad..7619dea08 100644 --- a/slither/solc_parsing/declarations/function.py +++ b/slither/solc_parsing/declarations/function.py @@ -27,6 +27,7 @@ from slither.utils.utils import unroll from slither.visitors.expression.export_values import ExportValues from slither.visitors.expression.has_conditional import HasConditional from slither.solc_parsing.exceptions import ParsingError +from slither.core.source_mapping.source_mapping import SourceMapping logger = logging.getLogger("FunctionSolc") @@ -835,6 +836,9 @@ class FunctionSolc(Function): def _parse_params(self, params): assert params[self.get_key()] == 'ParameterList' + self.parameters_src = SourceMapping() + self.parameters_src.set_offset(params['src'], self.contract.slither) + if self.is_compact_ast: params = params['parameters'] else: @@ -860,6 +864,9 @@ class FunctionSolc(Function): assert returns[self.get_key()] == 'ParameterList' + self.returns_src = SourceMapping() + self.returns_src.set_offset(returns['src'], self.contract.slither) + if self.is_compact_ast: returns = returns['parameters'] else: diff --git a/slither/solc_parsing/expressions/expression_parsing.py b/slither/solc_parsing/expressions/expression_parsing.py index 2dbb01bdf..e871c53d9 100644 --- a/slither/solc_parsing/expressions/expression_parsing.py +++ b/slither/solc_parsing/expressions/expression_parsing.py @@ -286,7 +286,9 @@ def parse_call(expression, caller_context): if isinstance(called, SuperCallExpression): return SuperCallExpression(called, arguments, type_return) - return CallExpression(called, arguments, type_return) + call_expression = CallExpression(called, arguments, type_return) + call_expression.set_offset(expression['src'], caller_context.slither) + return call_expression def parse_super_name(expression, is_compact_ast): if is_compact_ast: @@ -531,6 +533,7 @@ def parse_expression(expression, caller_context): var = find_variable(value, caller_context, referenced_declaration) identifier = Identifier(var) + identifier.set_offset(expression['src'], caller_context.slither) return identifier elif name == 'IndexAccess': @@ -659,6 +662,7 @@ def parse_expression(expression, caller_context): arguments = [parse_expression(a, caller_context) for a in children[1::]] call = CallExpression(called, arguments, 'Modifier') + call.set_offset(expression['src'], caller_context.slither) return call raise ParsingError('Expression not parsed %s'%name)