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}