1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Default, Serialize, Deserialize)]
5pub struct ForgeGuardConfig {
6 #[serde(default)]
8 pub deployment: DeploymentConfig,
9 #[serde(default)]
11 pub security: SecurityConfig,
12 #[serde(default)]
14 pub report: ReportConfig,
15 #[serde(default)]
17 pub cache: CacheConfig,
18 #[serde(default)]
20 pub plugins: PluginConfig,
21 #[serde(default)]
23 pub ai: AiConfig,
24 #[serde(default)]
26 pub notifications: NotificationConfig,
27 #[serde(default)]
29 pub history: HistoryConfig,
30}
31
32#[derive(Debug, Clone, Default, Serialize, Deserialize)]
40pub struct HistoryConfig {
41 #[serde(default)]
44 pub enabled: bool,
45 #[serde(default)]
49 pub db_path: Option<String>,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct DeploymentConfig {
55 #[serde(default = "default_min_score")]
57 pub min_score: u8,
58 #[serde(default = "default_true")]
60 pub block_on_high: bool,
61 #[serde(default)]
63 pub block_on_medium: bool,
64 #[serde(default = "default_true")]
66 pub block_on_critical: bool,
67 #[serde(default = "default_true")]
69 pub require_fuzzing: bool,
70 #[serde(default = "default_true")]
72 pub require_invariants: bool,
73 #[serde(default = "default_true")]
75 pub simulate_deployment: bool,
76 #[serde(default)]
78 pub require_verification: bool,
79 #[serde(default)]
81 pub auto_verify: bool,
82 #[serde(default)]
84 pub explorer_api_key: Option<String>,
85}
86
87fn default_min_score() -> u8 {
88 70
89}
90fn default_true() -> bool {
91 true
92}
93
94impl Default for DeploymentConfig {
95 fn default() -> Self {
96 Self {
97 min_score: 70,
98 block_on_high: true,
99 block_on_medium: false,
100 block_on_critical: true,
101 require_fuzzing: true,
102 require_invariants: true,
103 simulate_deployment: true,
104 require_verification: false,
105 auto_verify: false,
106 explorer_api_key: None,
107 }
108 }
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct SecurityConfig {
114 #[serde(default = "default_true")]
116 pub enable_high: bool,
117 #[serde(default = "default_true")]
119 pub enable_medium: bool,
120 #[serde(default = "default_true")]
122 pub enable_low: bool,
123 #[serde(default)]
125 pub enable_info: bool,
126 #[serde(default = "default_true")]
128 pub exploit_analysis: bool,
129 #[serde(default)]
131 pub gas_analysis: bool,
132 #[serde(default)]
134 pub bytecode_analysis: bool,
135 #[serde(default = "default_max_findings")]
137 pub max_findings_per_check: usize,
138 #[serde(default)]
140 pub severity_overrides: std::collections::HashMap<String, String>,
141 #[serde(default)]
144 pub enabled_checks: Vec<String>,
145 #[serde(default)]
147 pub disabled_checks: Vec<String>,
148}
149
150fn default_max_findings() -> usize {
151 50
152}
153
154impl Default for SecurityConfig {
155 fn default() -> Self {
156 Self {
157 enable_high: true,
158 enable_medium: true,
159 enable_low: true,
160 enable_info: false,
161 exploit_analysis: true,
162 gas_analysis: false,
163 bytecode_analysis: false,
164 max_findings_per_check: 50,
165 severity_overrides: std::collections::HashMap::new(),
166 enabled_checks: Vec::new(),
167 disabled_checks: Vec::new(),
168 }
169 }
170}
171
172#[derive(Debug, Clone, Serialize, Deserialize)]
174pub struct ReportConfig {
175 #[serde(default = "default_true")]
177 pub include_snippets: bool,
178 #[serde(default = "default_true")]
180 pub include_exploit_paths: bool,
181 #[serde(default = "default_true")]
183 pub include_recommendations: bool,
184 #[serde(default = "default_report_dir")]
186 pub output_dir: String,
187 #[serde(default)]
189 pub summary_only: bool,
190}
191
192fn default_report_dir() -> String {
193 "reports".into()
194}
195
196impl Default for ReportConfig {
197 fn default() -> Self {
198 Self {
199 include_snippets: true,
200 include_exploit_paths: true,
201 include_recommendations: true,
202 output_dir: default_report_dir(),
203 summary_only: false,
204 }
205 }
206}
207
208#[derive(Debug, Clone, Serialize, Deserialize)]
210pub struct CacheConfig {
211 #[serde(default = "default_true")]
213 pub enabled: bool,
214 #[serde(default = "default_cache_dir")]
216 pub directory: String,
217 #[serde(default = "default_cache_size")]
219 pub max_size_mb: u64,
220 #[serde(default = "default_cache_ttl")]
222 pub ttl_seconds: u64,
223}
224
225fn default_cache_dir() -> String {
226 ".forge-guard-cache".into()
227}
228fn default_cache_size() -> u64 {
229 500
230}
231fn default_cache_ttl() -> u64 {
232 3600
233}
234
235impl Default for CacheConfig {
236 fn default() -> Self {
237 Self {
238 enabled: true,
239 directory: default_cache_dir(),
240 max_size_mb: 500,
241 ttl_seconds: 3600,
242 }
243 }
244}
245
246#[derive(Debug, Clone, Serialize, Deserialize)]
248pub struct AiConfig {
249 #[serde(default = "default_ai_provider")]
251 pub provider: String,
252 #[serde(default = "default_ai_model")]
254 pub model: String,
255 #[serde(default = "default_ai_temperature")]
257 pub temperature: f64,
258 #[serde(default = "default_ai_max_tokens")]
260 pub max_tokens: u32,
261 #[serde(default = "default_ai_min_confidence")]
263 pub min_confidence: f64,
264 #[serde(default)]
266 pub full_audit: bool,
267}
268
269fn default_ai_provider() -> String {
270 "openai".into()
271}
272fn default_ai_model() -> String {
273 "gpt-4".into()
274}
275fn default_ai_temperature() -> f64 {
276 0.1
277}
278fn default_ai_max_tokens() -> u32 {
279 4000
280}
281fn default_ai_min_confidence() -> f64 {
282 0.5
283}
284
285impl Default for AiConfig {
286 fn default() -> Self {
287 Self {
288 provider: default_ai_provider(),
289 model: default_ai_model(),
290 temperature: default_ai_temperature(),
291 max_tokens: default_ai_max_tokens(),
292 min_confidence: default_ai_min_confidence(),
293 full_audit: false,
294 }
295 }
296}
297
298#[derive(Debug, Clone, Serialize, Deserialize)]
300pub struct PluginConfig {
301 #[serde(default = "default_plugin_dirs")]
303 pub directories: Vec<String>,
304 #[serde(default)]
306 pub enabled: Vec<String>,
307 #[serde(default)]
309 pub disabled: Vec<String>,
310 #[serde(default)]
312 pub allow_external: bool,
313}
314
315fn default_plugin_dirs() -> Vec<String> {
316 vec![".forge-guard/plugins".into()]
317}
318
319impl Default for PluginConfig {
320 fn default() -> Self {
321 Self {
322 directories: default_plugin_dirs(),
323 enabled: Vec::new(),
324 disabled: Vec::new(),
325 allow_external: false,
326 }
327 }
328}
329
330#[derive(Debug, Clone, Default, Serialize, Deserialize)]
342pub struct NotificationConfig {
343 #[serde(default)]
345 pub slack: NotificationEndpoint,
346 #[serde(default)]
348 pub discord: NotificationEndpoint,
349}
350
351#[derive(Debug, Clone, Serialize, Deserialize)]
353pub struct NotificationEndpoint {
354 #[serde(default)]
356 pub webhook: Option<String>,
357 #[serde(default = "default_notify_min_severity")]
360 pub min_severity: String,
361}
362
363fn default_notify_min_severity() -> String {
364 "high".into()
365}
366
367impl Default for NotificationEndpoint {
368 fn default() -> Self {
369 Self {
370 webhook: None,
371 min_severity: default_notify_min_severity(),
372 }
373 }
374}