1pub struct SecurityCheckMeta {
5 pub id: &'static str,
6 pub name: &'static str,
7 pub severity: &'static str,
8 pub description: &'static str,
9 pub details: &'static str,
10 pub remediation: &'static str,
11 pub category: &'static str,
12 pub blocks_deployment: bool,
13}
14
15pub const REENTRANCY: SecurityCheckMeta = SecurityCheckMeta {
20 id: "FA-H-001",
21 name: "Reentrancy",
22 severity: "high",
23 description: "Detects reentrancy vulnerabilities where external calls can recurse into the contract",
24 details: "Functions that make external calls after state changes can be re-entered, allowing attackers to drain funds or manipulate state. Common in withdraw patterns without checks-effects-interactions.",
25 remediation: "Follow checks-effects-interactions pattern. Use ReentrancyGuard from OpenZeppelin. Always update state before making external calls.",
26 category: "Access Control",
27 blocks_deployment: true,
28};
29
30pub const ACCESS_CONTROL: SecurityCheckMeta = SecurityCheckMeta {
31 id: "FA-H-002",
32 name: "Access Control",
33 severity: "high",
34 description: "Detects missing or incorrect access control modifiers",
35 details: "Functions that perform privileged operations without proper access control can be called by anyone. Common issues: missing onlyOwner, incorrect modifier checks, public init functions.",
36 remediation: "Use OpenZeppelin's Ownable or AccessControl. Ensure all privileged functions have proper modifiers. Avoid using tx.origin for authorization.",
37 category: "Access Control",
38 blocks_deployment: true,
39};
40
41pub const DELEGATECALL: SecurityCheckMeta = SecurityCheckMeta {
42 id: "FA-H-003",
43 name: "Delegatecall",
44 severity: "high",
45 description: "Detects unsafe delegatecall usage that can lead to storage corruption or code execution",
46 details: "delegatecall executes code from another contract in the caller's context. Unsafe patterns can lead to storage collisions, unexpected state changes, or malicious code execution in proxy patterns.",
47 remediation: "Validate delegatecall targets. Use a whitelist of allowed implementations. Check storage layout compatibility between proxy and implementation contracts.",
48 category: "Access Control",
49 blocks_deployment: true,
50};
51
52pub const TX_ORIGIN: SecurityCheckMeta = SecurityCheckMeta {
53 id: "FA-H-004",
54 name: "tx.origin Usage",
55 severity: "high",
56 description: "Detects tx.origin usage for authentication which is vulnerable to phishing",
57 details: "Using tx.origin for authorization allows intermediary contracts to impersonate the original caller. This can lead to phishing attacks where users lose funds.",
58 remediation: "Use msg.sender instead of tx.origin for authorization. tx.origin should only be used in very specific cases where you need the original external account.",
59 category: "Access Control",
60 blocks_deployment: true,
61};
62
63pub const CREATE2: SecurityCheckMeta = SecurityCheckMeta {
64 id: "FA-H-005",
65 name: "CREATE2 Vulnerabilities",
66 severity: "high",
67 description: "Detects issues with CREATE2 deterministic address deployment",
68 details: "CREATE2 allows deterministic contract addresses but can lead to address squatting, selfdestruct-recreate attacks, and unexpected contract replacement.",
69 remediation: "Use CREATE2 with salt derived from deployer-specific data. Consider adding deployment timeouts. Verify expected contract code at the computed address.",
70 category: "Deployment",
71 blocks_deployment: true,
72};
73
74pub const DOS: SecurityCheckMeta = SecurityCheckMeta {
75 id: "FA-H-006",
76 name: "Denial of Service",
77 severity: "high",
78 description: "Detects patterns that can lead to denial of service",
79 details: "Loops over dynamic arrays, unbounded gas consumption, reverting on expected external calls, and reliance on specific gas amounts can all be exploited to DoS the contract.",
80 remediation: "Use pull-over-push patterns for payments. Avoid iterating over dynamic arrays. Design for failure. Set reasonable gas limits for external calls.",
81 category: "Logic",
82 blocks_deployment: true,
83};
84
85pub const STORAGE_COLLISION: SecurityCheckMeta = SecurityCheckMeta {
86 id: "FA-H-007",
87 name: "Storage Collision",
88 severity: "high",
89 description: "Detects storage layout collisions in upgradeable contracts",
90 details: "In proxy patterns, changing the storage layout between implementations can cause variable collisions, corrupting contract state and potentially leading to loss of funds.",
91 remediation: "Maintain storage layout compatibility. Always append new variables. Use OpenZeppelin's upgradeable contracts plugin. Never reorder or delete existing state variables.",
92 category: "Upgradeability",
93 blocks_deployment: true,
94};
95
96pub const UNSAFE_ASSEMBLY: SecurityCheckMeta = SecurityCheckMeta {
97 id: "FA-H-008",
98 name: "Unsafe Assembly",
99 severity: "high",
100 description: "Detects unsafe inline assembly usage",
101 details: "Inline assembly bypasses Solidity's safety checks. Common issues: incorrect slot calculations, unsafe memory operations, and missing overflow checks in assembly arithmetic.",
102 remediation: "Minimize assembly usage. Validate all assembly operations carefully. Use Solidity's built-in functions when possible. Add extensive testing around assembly blocks.",
103 category: "Security",
104 blocks_deployment: true,
105};
106
107pub const SELFDESTRUCT: SecurityCheckMeta = SecurityCheckMeta {
108 id: "FA-H-009",
109 name: "Selfdestruct",
110 severity: "high",
111 description: "Detects selfdestruct usage that can destroy contract code",
112 details: "selfdestruct removes contract code and sends remaining ETH to a target address. In proxy patterns, selfdestruct can brick the proxy. Can also be used for CREATE2 address manipulation.",
113 remediation: "Avoid selfdestruct in upgradeable contracts. If necessary, use a timelock and multi-sig. Consider using SELFDESTRUCT only as a last resort with proper access control.",
114 category: "Security",
115 blocks_deployment: true,
116};
117
118pub const PROXY_VULNERABILITIES: SecurityCheckMeta = SecurityCheckMeta {
119 id: "FA-H-010",
120 name: "Proxy Vulnerabilities",
121 severity: "high",
122 description: "Detects proxy-related security issues",
123 details: "Proxy contracts introduce unique vulnerabilities: uninitialized implementations, selector clashes, unsafe delegatecall targets, and storage collisions.",
124 remediation: "Initialize implementations to prevent selfdestruct. Use transparent or UUPS patterns correctly. Verify storage layout compatibility. Test upgrade paths thoroughly.",
125 category: "Upgradeability",
126 blocks_deployment: true,
127};
128
129pub const ORACLE_MANIPULATION: SecurityCheckMeta = SecurityCheckMeta {
130 id: "FA-H-011",
131 name: "Oracle Manipulation",
132 severity: "high",
133 description: "Detects oracle price feed manipulation vulnerabilities",
134 details: "Using a single price oracle or a manipulable DEX price as an oracle can lead to price manipulation attacks, especially in lending, staking, and AMM protocols.",
135 remediation: "Use decentralized oracles like Chainlink. Implement TWAP or median pricing. Use multiple oracle sources and outlier detection. Add price deviation checks.",
136 category: "DeFi",
137 blocks_deployment: true,
138};
139
140pub const SIGNATURE_VULNERABILITIES: SecurityCheckMeta = SecurityCheckMeta {
141 id: "FA-H-012",
142 name: "Signature Vulnerabilities",
143 severity: "high",
144 description: "Detects signature verification vulnerabilities",
145 details: "Common issues: missing nonces allowing replay attacks, no expiry, EIP-2612 permit frontrunning, and signature malleability in ecrecover.",
146 remediation: "Include nonce, deadline, and chain ID in signed data. Use EIP-712 typed signatures. Prevent signature replay across chains. Use OpenZeppelin's SignatureChecker.",
147 category: "Cryptography",
148 blocks_deployment: true,
149};
150
151pub const REPLAY_ATTACKS: SecurityCheckMeta = SecurityCheckMeta {
152 id: "FA-H-013",
153 name: "Replay Attacks",
154 severity: "high",
155 description: "Detects cross-chain replay attack vulnerabilities",
156 details: "Without chain ID and nonce tracking in signatures, the same message can be replayed on different chains or multiple times, leading to unauthorized actions.",
157 remediation: "Include chainId and nonce in all signed messages. Track used nonces to prevent reuse. Use EIP-712 for structured signing with domain separator.",
158 category: "Cross-Chain",
159 blocks_deployment: true,
160};
161
162pub const ERC20_ISSUES: SecurityCheckMeta = SecurityCheckMeta {
163 id: "FA-H-014",
164 name: "ERC20 Issues",
165 severity: "high",
166 description: "Detects ERC20 implementation vulnerabilities",
167 details: "Common issues: missing return values, fee-on-transfer tokens, rebasing tokens, flash minting, and approval race conditions (the approve-frontrun issue).",
168 remediation: "Use OpenZeppelin's ERC20 implementation. Handle non-standard tokens safely. Use increaseAllowance/decreaseAllowance instead of approve. Check return values.",
169 category: "Standards",
170 blocks_deployment: true,
171};
172
173pub const BRIDGE_VULNERABILITIES: SecurityCheckMeta = SecurityCheckMeta {
174 id: "FA-H-015",
175 name: "Bridge Vulnerabilities",
176 severity: "high",
177 description: "Detects cross-chain bridge vulnerabilities",
178 details: "Bridge attacks can lead to catastrophic fund loss. Common issues: validator set manipulation, message relaying flaws, insufficient confirmation thresholds, and signature verification bugs.",
179 remediation: "Use battle-tested bridge architectures. Implement proper validator management. Add rate limiting and circuit breakers. Use fraud proofs or validity proofs where possible.",
180 category: "Cross-Chain",
181 blocks_deployment: true,
182};
183
184pub const FLASH_LOAN_ISSUES: SecurityCheckMeta = SecurityCheckMeta {
185 id: "FA-H-016",
186 name: "Flash Loan Issues",
187 severity: "high",
188 description: "Detects flash loan attack vector vulnerabilities",
189 details: "Protocols using spot prices, insufficient liquidity checks, or manipulable oracles are vulnerable to flash loan attacks that can drain protocol funds.",
190 remediation: "Use TWAP or manipulated-resistant oracles. Implement minimum liquidity requirements. Use time-weighted average prices. Add circuit breakers for abnormal price movements.",
191 category: "DeFi",
192 blocks_deployment: true,
193};
194
195pub const MEV_ISSUES: SecurityCheckMeta = SecurityCheckMeta {
196 id: "FA-H-017",
197 name: "MEV Vulnerabilities",
198 severity: "high",
199 description: "Detects maximal extractable value vulnerabilities",
200 details: "Frontrunning, sandwich attacks, and backrunning can extract value from users. Common issues: public mempool transactions with no slippage protection, visible order details.",
201 remediation: "Use commit-reveal schemes. Implement slippage protection. Use private mempools or MEV protection. Batch operations atomically. Add minimum output amounts.",
202 category: "DeFi",
203 blocks_deployment: true,
204};
205
206pub const CROSS_CHAIN_ISSUES: SecurityCheckMeta = SecurityCheckMeta {
207 id: "FA-H-018",
208 name: "Cross-Chain Issues",
209 severity: "high",
210 description: "Detects general cross-chain interoperability vulnerabilities",
211 details: "Cross-chain operations introduce unique risks: chain reorganization, message ordering, token representation mismatches, and bridge dependency risks.",
212 remediation: "Design for chain reorgs with confirmation requirements. Use canonical token representations. Ensure message atomicity. Add fallback mechanisms for bridge failures.",
213 category: "Cross-Chain",
214 blocks_deployment: true,
215};
216
217pub const DEPENDENCY_VULNERABILITIES: SecurityCheckMeta = SecurityCheckMeta {
218 id: "FA-H-019",
219 name: "Dependency Vulnerabilities",
220 severity: "high",
221 description: "Detects vulnerable or malicious dependencies",
222 details: "Using outdated or compromised dependencies can introduce vulnerabilities. Common issues: pinning to vulnerable versions, no integrity checks, and supply chain attacks.",
223 remediation: "Pin dependency versions. Use integrity verification (e.g., SRI). Keep dependencies updated. Audit dependency changes. Use tools like Dependabot or Snyk.",
224 category: "Dependencies",
225 blocks_deployment: true,
226};
227
228pub const UNSAFE_IMPORTS: SecurityCheckMeta = SecurityCheckMeta {
229 id: "FA-H-020",
230 name: "Unsafe Imports",
231 severity: "high",
232 description: "Detects unsafe or suspicious imports",
233 details: "Importing from untrusted sources, outdated versions, or suspicious-looking contracts can introduce vulnerabilities or malicious code into the project.",
234 remediation: "Use trusted sources only (OpenZeppelin, Solmate, etc.). Pin to specific versions. Verify import integrity. Use forge remappings consistently.",
235 category: "Dependencies",
236 blocks_deployment: true,
237};
238
239pub const UNSAFE_INITIALIZERS: SecurityCheckMeta = SecurityCheckMeta {
240 id: "FA-H-021",
241 name: "Unsafe Initializers",
242 severity: "high",
243 description: "Detects uninitialized upgradeable contracts",
244 details: "Implementation contracts without initialized guards can be selfdestructed. Proxy contracts can have their initializer called multiple times without reinitializer guards.",
245 remediation: "Use OpenZeppelin's Initializable with initializer modifier. Use reinitializer for version upgrades. Call disableInitializers in the implementation constructor.",
246 category: "Upgradeability",
247 blocks_deployment: true,
248};
249
250pub const UNSAFE_UPGRADE_PATHS: SecurityCheckMeta = SecurityCheckMeta {
251 id: "FA-H-022",
252 name: "Unsafe Upgrade Paths",
253 severity: "high",
254 description: "Detects unsafe contract upgrade paths",
255 details: "Upgradeable contracts need carefully managed upgrade paths. Common issues: storage layout breaks, missing reinitializers, and upgradeability without timelocks.",
256 remediation: "Use a timelock for upgrades. Maintain storage layout compatibility. Test upgrade paths. Use UUPS or transparent proxy patterns correctly.",
257 category: "Upgradeability",
258 blocks_deployment: true,
259};
260
261pub const CLONE_VULNERABILITIES: SecurityCheckMeta = SecurityCheckMeta {
262 id: "FA-H-023",
263 name: "Clone/ Minimal Proxy Issues",
264 severity: "high",
265 description: "Detects minimal proxy (EIP-1167) vulnerabilities",
266 details: "Clones share implementation storage and logic. Issues: uninitialized clones, implementation selfdestruct, and immutable variable expectations in proxied contracts.",
267 remediation: "Initialize each clone individually. Protect implementation from selfdestruct. Ensure clones have proper access control. Use Clones with initializer patterns.",
268 category: "Deployment",
269 blocks_deployment: true,
270};
271
272pub const GAS_PROBLEMS: SecurityCheckMeta = SecurityCheckMeta {
277 id: "FA-M-001",
278 name: "Gas Problems",
279 severity: "medium",
280 description: "Detects gas-inefficient patterns",
281 details: "Unbounded loops, redundant storage operations, repeated computations, and high-gas patterns can make contracts expensive or unusable.",
282 remediation: "Optimize storage usage. Use local variables. Minimize on-chain computations. Use appropriate data structures. Consider using ERC-1167 for clones.",
283 category: "Gas",
284 blocks_deployment: false,
285};
286
287pub const UNSAFE_CASTING: SecurityCheckMeta = SecurityCheckMeta {
288 id: "FA-M-002",
289 name: "Unsafe Casting",
290 severity: "medium",
291 description: "Detects unsafe type casting operations",
292 details: "Downcasting without overflow checks can lead to truncation. address payable conversions can fail silently. bytes<T> to string casts can produce invalid UTF-8.",
293 remediation: "Use OpenZeppelin's SafeCast library for downcasting. Validate addresses before payable conversion. Use string(bytes) carefully. Add input validation.",
294 category: "Logic",
295 blocks_deployment: false,
296};
297
298pub const TIMESTAMP_MANIPULATION: SecurityCheckMeta = SecurityCheckMeta {
299 id: "FA-M-003",
300 name: "Timestamp Manipulation",
301 severity: "medium",
302 description: "Detects reliance on block.timestamp for critical logic",
303 details: "block.timestamp can be manipulated by miners within a ~15-second window. Using it for critical randomness or time- sensitive logic is unsafe.",
304 remediation: "Use block.number for time intervals when possible. Don't use timestamp for randomness. Allow reasonable timestamp variance. Use trusted oracles for precise time.",
305 category: "Logic",
306 blocks_deployment: false,
307};
308
309pub const STORAGE_INEFFICIENCIES: SecurityCheckMeta = SecurityCheckMeta {
310 id: "FA-M-004",
311 name: "Storage Inefficiencies",
312 severity: "medium",
313 description: "Detects storage layout and packing inefficiencies",
314 details: "Poor storage layout wastes gas and can lead to slot overflow. Variables that fit in fewer slots should be packed together. Unnecessary storage variables increase costs.",
315 remediation: "Pack related state variables into fewer slots. Use appropriate data types (uint128, uint64, etc.). Delete unused storage. Use mappings for dynamic data.",
316 category: "Gas",
317 blocks_deployment: false,
318};
319
320pub const UNSAFE_EVENTS: SecurityCheckMeta = SecurityCheckMeta {
321 id: "FA-M-005",
322 name: "Unsafe Events",
323 severity: "medium",
324 description: "Detects events missing indexed parameters or emitting sensitive data",
325 details: "Events can leak sensitive information as they are stored on-chain permanently. Missing indexed parameters makes filtering difficult for off-chain services.",
326 remediation: "Index important parameters for efficient filtering. Never emit sensitive data in events. Follow the indexed parameter limit (max 3). Use EIP- standards for event signatures.",
327 category: "Best Practices",
328 blocks_deployment: false,
329};
330
331pub const POOR_VISIBILITY: SecurityCheckMeta = SecurityCheckMeta {
332 id: "FA-M-006",
333 name: "Poor Visibility Definitions",
334 severity: "medium",
335 description: "Detects incorrect or unsafe visibility modifiers",
336 details: "Functions marked as public or external when they should be internal or private can expand the attack surface. State variables exposed publicly may be unintended.",
337 remediation: "Use the most restrictive visibility modifier possible. Audit all public functions. Consider using external for functions only called externally. Mark state variables as private.",
338 category: "Best Practices",
339 blocks_deployment: false,
340};
341
342pub const BAD_MODIFIERS: SecurityCheckMeta = SecurityCheckMeta {
343 id: "FA-M-007",
344 name: "Bad Modifiers",
345 severity: "medium",
346 description: "Detects unsafe or incorrect modifier patterns",
347 details: "Modifiers that perform state changes, external calls, or have incorrect guard conditions can introduce vulnerabilities. Modifier side-effects are often unexpected.",
348 remediation: "Keep modifiers simple and read-only. Avoid external calls in modifiers. Don't create side effects in modifiers. Use functions instead of complex modifier logic.",
349 category: "Best Practices",
350 blocks_deployment: false,
351};
352
353pub const UNSAFE_MATH: SecurityCheckMeta = SecurityCheckMeta {
354 id: "FA-M-008",
355 name: "Unsafe Math Patterns",
356 severity: "medium",
357 description: "Detects math operations without proper overflow protection",
358 details: "While Solidity 0.8+ has built-in overflow checking, unchecked blocks and assembly math bypass these checks. Division before multiplication loses precision.",
359 remediation: "Use checked math by default. Only use unchecked blocks when overflow is impossible. Use FixedPointMath libraries for precision. Add input bounds.",
360 category: "Logic",
361 blocks_deployment: false,
362};
363
364pub const POOR_ACCESS_PATTERNS: SecurityCheckMeta = SecurityCheckMeta {
365 id: "FA-M-009",
366 name: "Poor Access Patterns",
367 severity: "medium",
368 description: "Detects suboptimal access patterns that increase gas or risk",
369 details: "Reading and writing storage repeatedly in loops, accessing storage when memory suffices, and redundant SLOAD operations waste gas and increase execution cost.",
370 remediation: "Cache storage reads in memory. Batch state changes. Minimize SLOAD/SSTORE operations. Use appropriate data structures for access patterns.",
371 category: "Gas",
372 blocks_deployment: false,
373};
374
375pub const NAMING_ISSUES: SecurityCheckMeta = SecurityCheckMeta {
380 id: "FA-L-001",
381 name: "Naming Issues",
382 severity: "low",
383 description: "Detects naming convention violations",
384 details: "Inconsistent naming (mixedCase for functions, UPPER_CASE for constants, etc.) makes code harder to read and audit. Misleading names can hide vulnerabilities.",
385 remediation: "Follow Solidity style guide: camelCase for functions and variables, UPPER_CASE for constants, underscore prefix for private. Use descriptive names.",
386 category: "Style",
387 blocks_deployment: false,
388};
389
390pub const CODE_DUPLICATION: SecurityCheckMeta = SecurityCheckMeta {
391 id: "FA-L-002",
392 name: "Code Duplication",
393 severity: "low",
394 description: "Detects repeated code patterns",
395 details: "Duplicate code increases maintenance burden and audit surface. Changes to one copy may not be applied to all, leading to inconsistency and potential bugs.",
396 remediation: "Extract common logic into internal functions or libraries. Use inheritance for shared functionality. Consider using modifiers for reusable checks.",
397 category: "Architecture",
398 blocks_deployment: false,
399};
400
401pub const OPTIMIZATION_ISSUES: SecurityCheckMeta = SecurityCheckMeta {
402 id: "FA-L-003",
403 name: "Optimization Suggestions",
404 severity: "low",
405 description: "Detects optimization opportunities",
406 details: "Using more gas than necessary due to suboptimal patterns: redundant operations, unnecessary storage, inefficient data structures, or missing compiler optimizations.",
407 remediation: "Enable compiler optimizer. Pack storage variables. Use calldata instead of memory for read-only parameters. Minimize external calls. Use appropriate data types.",
408 category: "Gas",
409 blocks_deployment: false,
410};
411
412pub const STYLE_ISSUES: SecurityCheckMeta = SecurityCheckMeta {
417 id: "FA-I-001",
418 name: "Style Issues",
419 severity: "informational",
420 description: "Detects style guide violations",
421 details: "Deviations from the Solidity Style Guide: incorrect indentation, missing or extra spaces, ordering of functions (external, public, internal, private), and NatSpec comments.",
422 remediation: "Follow the official Solidity Style Guide. Use forge fmt for automatic formatting. Add NatSpec documentation to all functions. Use consistent layouts.",
423 category: "Style",
424 blocks_deployment: false,
425};
426
427pub const DOCUMENTATION_ISSUES: SecurityCheckMeta = SecurityCheckMeta {
428 id: "FA-I-002",
429 name: "Missing Documentation",
430 severity: "informational",
431 description: "Detects missing or insufficient NatSpec documentation",
432 details: "Contracts, functions, and state variables without NatSpec comments are harder to audit and maintain. Documentation is critical for security review.",
433 remediation: "Add @notice, @param, @return, @dev tags to all functions. Document state variables. Add custom errors documentation. Include usage examples and security assumptions.",
434 category: "Documentation",
435 blocks_deployment: false,
436};
437
438pub const ALL_CHECKS: &[SecurityCheckMeta] = &[
443 REENTRANCY,
445 ACCESS_CONTROL,
446 DELEGATECALL,
447 TX_ORIGIN,
448 CREATE2,
449 DOS,
450 STORAGE_COLLISION,
451 UNSAFE_ASSEMBLY,
452 SELFDESTRUCT,
453 PROXY_VULNERABILITIES,
454 ORACLE_MANIPULATION,
455 SIGNATURE_VULNERABILITIES,
456 REPLAY_ATTACKS,
457 ERC20_ISSUES,
458 BRIDGE_VULNERABILITIES,
459 FLASH_LOAN_ISSUES,
460 MEV_ISSUES,
461 CROSS_CHAIN_ISSUES,
462 DEPENDENCY_VULNERABILITIES,
463 UNSAFE_IMPORTS,
464 UNSAFE_INITIALIZERS,
465 UNSAFE_UPGRADE_PATHS,
466 CLONE_VULNERABILITIES,
467 GAS_PROBLEMS,
469 UNSAFE_CASTING,
470 TIMESTAMP_MANIPULATION,
471 STORAGE_INEFFICIENCIES,
472 UNSAFE_EVENTS,
473 POOR_VISIBILITY,
474 BAD_MODIFIERS,
475 UNSAFE_MATH,
476 POOR_ACCESS_PATTERNS,
477 NAMING_ISSUES,
479 CODE_DUPLICATION,
480 OPTIMIZATION_ISSUES,
481 STYLE_ISSUES,
483 DOCUMENTATION_ISSUES,
484];
485
486pub const fn check_count() -> usize {
488 ALL_CHECKS.len()
489}