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 #[serde(default)]
118 pub enabled_checks: Vec<String>,
119 #[serde(default)]
121 pub disabled_checks: Vec<String>,
122}
123
124fn default_max_findings() -> usize {
125 50
126}
127
128impl Default for SecurityConfig {
129 fn default() -> Self {
130 Self {
131 enable_high: true,
132 enable_medium: true,
133 enable_low: true,
134 enable_info: false,
135 exploit_analysis: true,
136 gas_analysis: false,
137 bytecode_analysis: false,
138 max_findings_per_check: 50,
139 severity_overrides: std::collections::HashMap::new(),
140 enabled_checks: Vec::new(),
141 disabled_checks: Vec::new(),
142 }
143 }
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
148pub struct ReportConfig {
149 #[serde(default = "default_true")]
151 pub include_snippets: bool,
152 #[serde(default = "default_true")]
154 pub include_exploit_paths: bool,
155 #[serde(default = "default_true")]
157 pub include_recommendations: bool,
158 #[serde(default = "default_report_dir")]
160 pub output_dir: String,
161 #[serde(default)]
163 pub summary_only: bool,
164}
165
166fn default_report_dir() -> String {
167 "reports".into()
168}
169
170impl Default for ReportConfig {
171 fn default() -> Self {
172 Self {
173 include_snippets: true,
174 include_exploit_paths: true,
175 include_recommendations: true,
176 output_dir: default_report_dir(),
177 summary_only: false,
178 }
179 }
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
184pub struct CacheConfig {
185 #[serde(default = "default_true")]
187 pub enabled: bool,
188 #[serde(default = "default_cache_dir")]
190 pub directory: String,
191 #[serde(default = "default_cache_size")]
193 pub max_size_mb: u64,
194 #[serde(default = "default_cache_ttl")]
196 pub ttl_seconds: u64,
197}
198
199fn default_cache_dir() -> String {
200 ".forge-guard-cache".into()
201}
202fn default_cache_size() -> u64 {
203 500
204}
205fn default_cache_ttl() -> u64 {
206 3600
207}
208
209impl Default for CacheConfig {
210 fn default() -> Self {
211 Self {
212 enabled: true,
213 directory: default_cache_dir(),
214 max_size_mb: 500,
215 ttl_seconds: 3600,
216 }
217 }
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct AiConfig {
223 #[serde(default = "default_ai_provider")]
225 pub provider: String,
226 #[serde(default = "default_ai_model")]
228 pub model: String,
229 #[serde(default = "default_ai_temperature")]
231 pub temperature: f64,
232 #[serde(default = "default_ai_max_tokens")]
234 pub max_tokens: u32,
235 #[serde(default = "default_ai_min_confidence")]
237 pub min_confidence: f64,
238 #[serde(default)]
240 pub full_audit: bool,
241}
242
243fn default_ai_provider() -> String {
244 "openai".into()
245}
246fn default_ai_model() -> String {
247 "gpt-4".into()
248}
249fn default_ai_temperature() -> f64 {
250 0.1
251}
252fn default_ai_max_tokens() -> u32 {
253 4000
254}
255fn default_ai_min_confidence() -> f64 {
256 0.5
257}
258
259impl Default for AiConfig {
260 fn default() -> Self {
261 Self {
262 provider: default_ai_provider(),
263 model: default_ai_model(),
264 temperature: default_ai_temperature(),
265 max_tokens: default_ai_max_tokens(),
266 min_confidence: default_ai_min_confidence(),
267 full_audit: false,
268 }
269 }
270}
271
272#[derive(Debug, Clone, Serialize, Deserialize)]
274pub struct PluginConfig {
275 #[serde(default = "default_plugin_dirs")]
277 pub directories: Vec<String>,
278 #[serde(default)]
280 pub enabled: Vec<String>,
281 #[serde(default)]
283 pub disabled: Vec<String>,
284 #[serde(default)]
286 pub allow_external: bool,
287}
288
289fn default_plugin_dirs() -> Vec<String> {
290 vec![".forge-guard/plugins".into()]
291}
292
293impl Default for PluginConfig {
294 fn default() -> Self {
295 Self {
296 directories: default_plugin_dirs(),
297 enabled: Vec::new(),
298 disabled: Vec::new(),
299 allow_external: false,
300 }
301 }
302}