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}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct DeploymentConfig {
29 #[serde(default = "default_min_score")]
31 pub min_score: u8,
32 #[serde(default = "default_true")]
34 pub block_on_high: bool,
35 #[serde(default)]
37 pub block_on_medium: bool,
38 #[serde(default = "default_true")]
40 pub block_on_critical: bool,
41 #[serde(default = "default_true")]
43 pub require_fuzzing: bool,
44 #[serde(default = "default_true")]
46 pub require_invariants: bool,
47 #[serde(default = "default_true")]
49 pub simulate_deployment: bool,
50 #[serde(default)]
52 pub require_verification: bool,
53 #[serde(default)]
55 pub auto_verify: bool,
56 #[serde(default)]
58 pub explorer_api_key: Option<String>,
59}
60
61fn default_min_score() -> u8 {
62 70
63}
64fn default_true() -> bool {
65 true
66}
67
68impl Default for DeploymentConfig {
69 fn default() -> Self {
70 Self {
71 min_score: 70,
72 block_on_high: true,
73 block_on_medium: false,
74 block_on_critical: true,
75 require_fuzzing: true,
76 require_invariants: true,
77 simulate_deployment: true,
78 require_verification: false,
79 auto_verify: false,
80 explorer_api_key: None,
81 }
82 }
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct SecurityConfig {
88 #[serde(default = "default_true")]
90 pub enable_high: bool,
91 #[serde(default = "default_true")]
93 pub enable_medium: bool,
94 #[serde(default = "default_true")]
96 pub enable_low: bool,
97 #[serde(default)]
99 pub enable_info: bool,
100 #[serde(default = "default_true")]
102 pub exploit_analysis: bool,
103 #[serde(default)]
105 pub gas_analysis: bool,
106 #[serde(default)]
108 pub bytecode_analysis: bool,
109 #[serde(default = "default_max_findings")]
111 pub max_findings_per_check: usize,
112 #[serde(default)]
114 pub severity_overrides: std::collections::HashMap<String, String>,
115}
116
117fn default_max_findings() -> usize {
118 50
119}
120
121impl Default for SecurityConfig {
122 fn default() -> Self {
123 Self {
124 enable_high: true,
125 enable_medium: true,
126 enable_low: true,
127 enable_info: false,
128 exploit_analysis: true,
129 gas_analysis: false,
130 bytecode_analysis: false,
131 max_findings_per_check: 50,
132 severity_overrides: std::collections::HashMap::new(),
133 }
134 }
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
139pub struct ReportConfig {
140 #[serde(default = "default_true")]
142 pub include_snippets: bool,
143 #[serde(default = "default_true")]
145 pub include_exploit_paths: bool,
146 #[serde(default = "default_true")]
148 pub include_recommendations: bool,
149 #[serde(default = "default_report_dir")]
151 pub output_dir: String,
152 #[serde(default)]
154 pub summary_only: bool,
155}
156
157fn default_report_dir() -> String {
158 "reports".into()
159}
160
161impl Default for ReportConfig {
162 fn default() -> Self {
163 Self {
164 include_snippets: true,
165 include_exploit_paths: true,
166 include_recommendations: true,
167 output_dir: default_report_dir(),
168 summary_only: false,
169 }
170 }
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize)]
175pub struct CacheConfig {
176 #[serde(default = "default_true")]
178 pub enabled: bool,
179 #[serde(default = "default_cache_dir")]
181 pub directory: String,
182 #[serde(default = "default_cache_size")]
184 pub max_size_mb: u64,
185 #[serde(default = "default_cache_ttl")]
187 pub ttl_seconds: u64,
188}
189
190fn default_cache_dir() -> String {
191 ".forge-guard-cache".into()
192}
193fn default_cache_size() -> u64 {
194 500
195}
196fn default_cache_ttl() -> u64 {
197 3600
198}
199
200impl Default for CacheConfig {
201 fn default() -> Self {
202 Self {
203 enabled: true,
204 directory: default_cache_dir(),
205 max_size_mb: 500,
206 ttl_seconds: 3600,
207 }
208 }
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct AiConfig {
214 #[serde(default = "default_ai_provider")]
216 pub provider: String,
217 #[serde(default = "default_ai_model")]
219 pub model: String,
220 #[serde(default = "default_ai_temperature")]
222 pub temperature: f64,
223 #[serde(default = "default_ai_max_tokens")]
225 pub max_tokens: u32,
226 #[serde(default = "default_ai_min_confidence")]
228 pub min_confidence: f64,
229 #[serde(default)]
231 pub full_audit: bool,
232}
233
234fn default_ai_provider() -> String {
235 "openai".into()
236}
237fn default_ai_model() -> String {
238 "gpt-4".into()
239}
240fn default_ai_temperature() -> f64 {
241 0.1
242}
243fn default_ai_max_tokens() -> u32 {
244 4000
245}
246fn default_ai_min_confidence() -> f64 {
247 0.5
248}
249
250impl Default for AiConfig {
251 fn default() -> Self {
252 Self {
253 provider: default_ai_provider(),
254 model: default_ai_model(),
255 temperature: default_ai_temperature(),
256 max_tokens: default_ai_max_tokens(),
257 min_confidence: default_ai_min_confidence(),
258 full_audit: false,
259 }
260 }
261}
262
263#[derive(Debug, Clone, Serialize, Deserialize)]
265pub struct PluginConfig {
266 #[serde(default = "default_plugin_dirs")]
268 pub directories: Vec<String>,
269 #[serde(default)]
271 pub enabled: Vec<String>,
272 #[serde(default)]
274 pub disabled: Vec<String>,
275 #[serde(default)]
277 pub allow_external: bool,
278}
279
280fn default_plugin_dirs() -> Vec<String> {
281 vec![".forge-guard/plugins".into()]
282}
283
284impl Default for PluginConfig {
285 fn default() -> Self {
286 Self {
287 directories: default_plugin_dirs(),
288 enabled: Vec::new(),
289 disabled: Vec::new(),
290 allow_external: false,
291 }
292 }
293}