slither.vyper_parsing.vyper_compilation_unit
1from typing import Dict 2import os 3import re 4from dataclasses import dataclass, field 5from slither.core.declarations import Contract 6from slither.core.compilation_unit import SlitherCompilationUnit 7from slither.vyper_parsing.declarations.contract import ContractVyper 8from slither.analyses.data_dependency.data_dependency import compute_dependency 9from slither.vyper_parsing.ast.types import Module 10from slither.exceptions import SlitherException 11 12 13@dataclass 14class VyperCompilationUnit: 15 _compilation_unit: SlitherCompilationUnit 16 _parsed: bool = False 17 _analyzed: bool = False 18 _underlying_contract_to_parser: Dict[Contract, ContractVyper] = field(default_factory=dict) 19 _contracts_by_id: Dict[int, Contract] = field(default_factory=dict) 20 21 def parse_module(self, data: Module, filename: str): 22 23 sourceUnit_candidates = re.findall("[0-9]*:[0-9]*:([0-9]*)", data.src) 24 assert len(sourceUnit_candidates) == 1, "Source unit not found" 25 sourceUnit = int(sourceUnit_candidates[0]) 26 27 self._compilation_unit.source_units[sourceUnit] = filename 28 if os.path.isfile(filename) and filename not in self._compilation_unit.core.source_code: 29 self._compilation_unit.core.add_source_code(filename) 30 31 scope = self._compilation_unit.get_scope(filename) 32 contract = Contract(self._compilation_unit, scope) 33 contract_parser = ContractVyper(self, contract, data) 34 contract.set_offset(data.src, self._compilation_unit) 35 36 self._underlying_contract_to_parser[contract] = contract_parser 37 38 def parse_contracts(self): 39 for contract, contract_parser in self._underlying_contract_to_parser.items(): 40 self._contracts_by_id[contract.id] = contract 41 self._compilation_unit.contracts.append(contract) 42 43 contract_parser.parse_enums() 44 contract_parser.parse_structs() 45 contract_parser.parse_state_variables() 46 contract_parser.parse_events() 47 contract_parser.parse_functions() 48 49 self._parsed = True 50 51 def analyze_contracts(self) -> None: 52 if not self._parsed: 53 raise SlitherException("Parse the contract before running analyses") 54 55 for contract_parser in self._underlying_contract_to_parser.values(): 56 # State variables are analyzed for all contracts because interfaces may 57 # reference them, specifically, constants. 58 contract_parser.analyze_state_variables() 59 60 for contract_parser in self._underlying_contract_to_parser.values(): 61 contract_parser.analyze() 62 63 self._convert_to_slithir() 64 65 compute_dependency(self._compilation_unit) 66 67 self._analyzed = True 68 69 def _convert_to_slithir(self) -> None: 70 for contract in self._compilation_unit.contracts: 71 contract.add_constructor_variables() 72 for func in contract.functions: 73 func.generate_slithir_and_analyze() 74 75 contract.convert_expression_to_slithir_ssa() 76 77 self._compilation_unit.propagate_function_calls() 78 for contract in self._compilation_unit.contracts: 79 contract.fix_phi() 80 contract.update_read_write_using_ssa()
class
VyperCompilationUnit:
15class VyperCompilationUnit: 16 _compilation_unit: SlitherCompilationUnit 17 _parsed: bool = False 18 _analyzed: bool = False 19 _underlying_contract_to_parser: Dict[Contract, ContractVyper] = field(default_factory=dict) 20 _contracts_by_id: Dict[int, Contract] = field(default_factory=dict) 21 22 def parse_module(self, data: Module, filename: str): 23 24 sourceUnit_candidates = re.findall("[0-9]*:[0-9]*:([0-9]*)", data.src) 25 assert len(sourceUnit_candidates) == 1, "Source unit not found" 26 sourceUnit = int(sourceUnit_candidates[0]) 27 28 self._compilation_unit.source_units[sourceUnit] = filename 29 if os.path.isfile(filename) and filename not in self._compilation_unit.core.source_code: 30 self._compilation_unit.core.add_source_code(filename) 31 32 scope = self._compilation_unit.get_scope(filename) 33 contract = Contract(self._compilation_unit, scope) 34 contract_parser = ContractVyper(self, contract, data) 35 contract.set_offset(data.src, self._compilation_unit) 36 37 self._underlying_contract_to_parser[contract] = contract_parser 38 39 def parse_contracts(self): 40 for contract, contract_parser in self._underlying_contract_to_parser.items(): 41 self._contracts_by_id[contract.id] = contract 42 self._compilation_unit.contracts.append(contract) 43 44 contract_parser.parse_enums() 45 contract_parser.parse_structs() 46 contract_parser.parse_state_variables() 47 contract_parser.parse_events() 48 contract_parser.parse_functions() 49 50 self._parsed = True 51 52 def analyze_contracts(self) -> None: 53 if not self._parsed: 54 raise SlitherException("Parse the contract before running analyses") 55 56 for contract_parser in self._underlying_contract_to_parser.values(): 57 # State variables are analyzed for all contracts because interfaces may 58 # reference them, specifically, constants. 59 contract_parser.analyze_state_variables() 60 61 for contract_parser in self._underlying_contract_to_parser.values(): 62 contract_parser.analyze() 63 64 self._convert_to_slithir() 65 66 compute_dependency(self._compilation_unit) 67 68 self._analyzed = True 69 70 def _convert_to_slithir(self) -> None: 71 for contract in self._compilation_unit.contracts: 72 contract.add_constructor_variables() 73 for func in contract.functions: 74 func.generate_slithir_and_analyze() 75 76 contract.convert_expression_to_slithir_ssa() 77 78 self._compilation_unit.propagate_function_calls() 79 for contract in self._compilation_unit.contracts: 80 contract.fix_phi() 81 contract.update_read_write_using_ssa()
VyperCompilationUnit( _compilation_unit: slither.core.compilation_unit.SlitherCompilationUnit, _parsed: bool = False, _analyzed: bool = False, _underlying_contract_to_parser: Dict[slither.core.declarations.contract.Contract, slither.vyper_parsing.declarations.contract.ContractVyper] = <factory>, _contracts_by_id: Dict[int, slither.core.declarations.contract.Contract] = <factory>)
22 def parse_module(self, data: Module, filename: str): 23 24 sourceUnit_candidates = re.findall("[0-9]*:[0-9]*:([0-9]*)", data.src) 25 assert len(sourceUnit_candidates) == 1, "Source unit not found" 26 sourceUnit = int(sourceUnit_candidates[0]) 27 28 self._compilation_unit.source_units[sourceUnit] = filename 29 if os.path.isfile(filename) and filename not in self._compilation_unit.core.source_code: 30 self._compilation_unit.core.add_source_code(filename) 31 32 scope = self._compilation_unit.get_scope(filename) 33 contract = Contract(self._compilation_unit, scope) 34 contract_parser = ContractVyper(self, contract, data) 35 contract.set_offset(data.src, self._compilation_unit) 36 37 self._underlying_contract_to_parser[contract] = contract_parser
def
parse_contracts(self):
39 def parse_contracts(self): 40 for contract, contract_parser in self._underlying_contract_to_parser.items(): 41 self._contracts_by_id[contract.id] = contract 42 self._compilation_unit.contracts.append(contract) 43 44 contract_parser.parse_enums() 45 contract_parser.parse_structs() 46 contract_parser.parse_state_variables() 47 contract_parser.parse_events() 48 contract_parser.parse_functions() 49 50 self._parsed = True
def
analyze_contracts(self) -> None:
52 def analyze_contracts(self) -> None: 53 if not self._parsed: 54 raise SlitherException("Parse the contract before running analyses") 55 56 for contract_parser in self._underlying_contract_to_parser.values(): 57 # State variables are analyzed for all contracts because interfaces may 58 # reference them, specifically, constants. 59 contract_parser.analyze_state_variables() 60 61 for contract_parser in self._underlying_contract_to_parser.values(): 62 contract_parser.analyze() 63 64 self._convert_to_slithir() 65 66 compute_dependency(self._compilation_unit) 67 68 self._analyzed = True