diff --git a/slither/solc_parsing/declarations/contract.py b/slither/solc_parsing/declarations/contract.py index 03ff2dc54..7522e9f84 100644 --- a/slither/solc_parsing/declarations/contract.py +++ b/slither/solc_parsing/declarations/contract.py @@ -36,6 +36,9 @@ class ContractSolc04(Contract): self._is_analyzed = False + # use to remap inheritance id + self._remapping = {} + # Export info if self.is_compact_ast: self._name = self._data['name'] @@ -49,6 +52,7 @@ class ContractSolc04(Contract): self._parse_contract_info() self._parse_contract_items() + @property def is_analyzed(self): return self._is_analyzed @@ -61,6 +65,10 @@ class ContractSolc04(Contract): return key return 'children' + @property + def remapping(self): + return self._remapping + @property def is_compact_ast(self): return self.slither.is_compact_ast @@ -82,6 +90,12 @@ class ContractSolc04(Contract): self.linearizedBaseContracts = attributes['linearizedBaseContracts'] self.fullyImplemented = attributes['fullyImplemented'] + # trufle does some re-mapping of id + if 'baseContracts' in self._data: + for elem in self._data['baseContracts']: + if elem['nodeType'] == 'InheritanceSpecifier': + self._remapping[elem['baseName']['referencedDeclaration']] = elem['baseName']['name'] + def _parse_contract_items(self): if not self.get_children() in self._data: # empty contract return diff --git a/slither/solc_parsing/expressions/expression_parsing.py b/slither/solc_parsing/expressions/expression_parsing.py index 02d095cc8..a12fe4307 100644 --- a/slither/solc_parsing/expressions/expression_parsing.py +++ b/slither/solc_parsing/expressions/expression_parsing.py @@ -47,7 +47,7 @@ def get_pointer_name(variable): return None -def find_variable(var_name, caller_context): +def find_variable(var_name, caller_context, referenced_declaration=None): if isinstance(caller_context, Contract): function = None @@ -123,6 +123,11 @@ def find_variable(var_name, caller_context): if var_name in contracts: return contracts[var_name] + if referenced_declaration: + for contract in contract.slither.contracts: + if contract.id == referenced_declaration: + return contract + raise VariableNotFound('Variable not found: {}'.format(var_name)) @@ -406,7 +411,11 @@ def parse_expression(expression, caller_context): value = value+'('+found[0]+')' value = filter_name(value) - var = find_variable(value, caller_context) + if 'referencedDeclaration' in expression: + referenced_declaration = expression['referencedDeclaration'] + else: + referenced_declaration = None + var = find_variable(value, caller_context, referenced_declaration) identifier = Identifier(var) return identifier diff --git a/slither/solc_parsing/slitherSolc.py b/slither/solc_parsing/slitherSolc.py index ec7383fe2..e9994c116 100644 --- a/slither/solc_parsing/slitherSolc.py +++ b/slither/solc_parsing/slitherSolc.py @@ -142,7 +142,13 @@ class SlitherSolc(Slither): # Update of the inheritance for contract in self._contractsNotParsed: # remove the first elem in linearizedBaseContracts as it is the contract itself - contract.setInheritance([self._contracts_by_id[i] for i in contract.linearizedBaseContracts[1:]]) + fathers = [] + for i in contract.linearizedBaseContracts[1:]: + if i in contract.remapping: + fathers.append(self.get_contract_from_name(contract.remapping[i])) + else: + fathers.append(self._contracts_by_id[i]) + contract.setInheritance(fathers) contracts_to_be_analyzed = self.contracts