Skip to main content

thalir_core/
contract.rs

1use crate::function::Function;
2use crate::source_location::SourceFiles;
3use crate::types::Type;
4use indexmap::IndexMap;
5use num_bigint::BigUint;
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Contract {
10    pub name: String,
11    pub functions: IndexMap<String, Function>,
12    pub storage_layout: StorageLayout,
13    pub events: Vec<EventDefinition>,
14    pub modifiers: Vec<ModifierDefinition>,
15    pub constants: Vec<ConstantDefinition>,
16    pub metadata: ContractMetadata,
17    #[serde(skip)]
18    pub source_files: SourceFiles,
19}
20
21impl Contract {
22    pub fn new(name: String) -> Self {
23        Self {
24            name,
25            functions: IndexMap::new(),
26            storage_layout: StorageLayout::default(),
27            events: Vec::new(),
28            modifiers: Vec::new(),
29            constants: Vec::new(),
30            metadata: ContractMetadata::default(),
31            source_files: SourceFiles::new(),
32        }
33    }
34
35    pub fn add_function(&mut self, mut function: Function) {
36        function.analyze_metadata();
37        self.functions
38            .insert(function.signature.name.clone(), function);
39    }
40
41    pub fn get_function(&self, name: &str) -> Option<&Function> {
42        self.functions.get(name)
43    }
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize, Default)]
47pub struct ContractMetadata {
48    pub version: String,
49    pub security_flags: SecurityFlags,
50    pub optimization_level: OptLevel,
51    pub source_hash: Option<[u8; 32]>,
52    pub source_file: Option<String>,
53    pub source_code: Option<String>,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize, Default)]
57pub struct SecurityFlags {
58    pub has_external_calls: bool,
59    pub has_delegatecalls: bool,
60    pub has_selfdestruct: bool,
61    pub has_assembly: bool,
62    pub is_upgradeable: bool,
63    pub uses_randomness: bool,
64}
65
66#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)]
67pub enum OptLevel {
68    #[default]
69    None,
70    Size,
71    Speed,
72    SpeedAndSize,
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize, Default)]
76pub struct StorageLayout {
77    pub slots: Vec<StorageSlot>,
78    pub mappings: Vec<MappingLayout>,
79    pub arrays: Vec<ArrayLayout>,
80    pub structs: Vec<StructLayout>,
81}
82
83impl StorageLayout {
84    pub fn add_variable(&mut self, name: String, ty: Type, slot: u32) {
85        self.slots.push(StorageSlot {
86            slot: BigUint::from(slot),
87            offset: 0,
88            var_type: ty,
89            name,
90            packed_with: Vec::new(),
91        });
92    }
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize)]
96pub struct StorageSlot {
97    pub slot: BigUint,
98    pub offset: u8,
99    pub var_type: Type,
100    pub name: String,
101    pub packed_with: Vec<PackedVariable>,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct PackedVariable {
106    pub name: String,
107    pub offset: u8,
108    pub size: u8,
109    pub var_type: Type,
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct MappingLayout {
114    pub base_slot: BigUint,
115    pub key_type: Type,
116    pub value_type: Type,
117    pub name: String,
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct ArrayLayout {
122    pub base_slot: BigUint,
123    pub element_type: Type,
124    pub is_dynamic: bool,
125    pub name: String,
126}
127
128#[derive(Debug, Clone, Serialize, Deserialize)]
129pub struct StructLayout {
130    pub base_slot: BigUint,
131    pub fields: Vec<StructField>,
132    pub name: String,
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct StructField {
137    pub name: String,
138    pub field_type: Type,
139    pub offset: u8,
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize)]
143pub struct EventDefinition {
144    pub id: EventId,
145    pub name: String,
146    pub parameters: Vec<EventParameter>,
147    pub anonymous: bool,
148}
149
150#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
151pub struct EventId(pub u32);
152
153#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct EventParameter {
155    pub name: String,
156    pub param_type: Type,
157    pub indexed: bool,
158}
159
160#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct ModifierDefinition {
162    pub id: ModifierId,
163    pub name: String,
164    pub parameters: Vec<ModifierParameter>,
165    pub body: ModifierBody,
166}
167
168#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
169pub struct ModifierId(pub u32);
170
171#[derive(Debug, Clone, Serialize, Deserialize)]
172pub struct ModifierParameter {
173    pub name: String,
174    pub param_type: Type,
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize)]
178pub struct ModifierBody {}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
181pub struct ModifierRef {
182    pub id: ModifierId,
183    pub arguments: Vec<crate::values::Value>,
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize)]
187pub struct ConstantDefinition {
188    pub name: String,
189    pub const_type: Type,
190    pub value: crate::values::Constant,
191}