audit-system 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +351 -0
  3. package/agents/AGENT_REGISTRY.md +150 -0
  4. package/agents/assumption-analyzer.json +7 -0
  5. package/agents/assumption-analyzer.md +37 -0
  6. package/agents/composition-attacker.json +7 -0
  7. package/agents/composition-attacker.md +46 -0
  8. package/agents/economic-attacker.json +7 -0
  9. package/agents/economic-attacker.md +43 -0
  10. package/agents/exploit-writer.json +7 -0
  11. package/agents/exploit-writer.md +48 -0
  12. package/agents/orchestrator.json +16 -0
  13. package/agents/orchestrator.md +46 -0
  14. package/agents/report-writer.json +7 -0
  15. package/agents/report-writer.md +52 -0
  16. package/agents/state-machine-hacker.json +7 -0
  17. package/agents/state-machine-hacker.md +43 -0
  18. package/agents/test-generator.json +7 -0
  19. package/agents/test-generator.md +49 -0
  20. package/cli.js +93 -0
  21. package/config.json +74 -0
  22. package/lib/detect-lang.js +109 -0
  23. package/lib/install.js +229 -0
  24. package/lib/utils.js +41 -0
  25. package/obsidian-vault/README.md +103 -0
  26. package/obsidian-vault/attack-patterns/state-inconsistency.md +90 -0
  27. package/obsidian-vault/exploits/_index.md +109 -0
  28. package/obsidian-vault/exploits/beanstalk-2022.md +334 -0
  29. package/obsidian-vault/exploits/nomad-2022.md +295 -0
  30. package/obsidian-vault/exploits/ronin-2022.md +251 -0
  31. package/obsidian-vault/exploits/wormhole-2022.md +284 -0
  32. package/obsidian-vault/failed-hypotheses/_template.md +77 -0
  33. package/obsidian-vault/hypotheses/_template.md +43 -0
  34. package/obsidian-vault/hypotheses/bridge-protocol-template.md +254 -0
  35. package/obsidian-vault/hypotheses/dex-protocol-template.md +185 -0
  36. package/obsidian-vault/hypotheses/governance-protocol-template.md +263 -0
  37. package/obsidian-vault/hypotheses/lending-protocol-template.md +218 -0
  38. package/obsidian-vault/hypotheses/staking-protocol-template.md +223 -0
  39. package/obsidian-vault/invariant-catalog/defi-invariants.md +307 -0
  40. package/obsidian-vault/invariant-catalog/solana-invariants.md +213 -0
  41. package/obsidian-vault/novel-patterns/pattern-mutation-framework.md +316 -0
  42. package/obsidian-vault/reports/_template.md +92 -0
  43. package/obsidian-vault/research/cross-protocol-analysis/.gitkeep +0 -0
  44. package/obsidian-vault/research/emerging-threats/.gitkeep +0 -0
  45. package/obsidian-vault/research/protocol-specific/.gitkeep +0 -0
  46. package/obsidian-vault/test-strategies/fuzzing.md +75 -0
  47. package/obsidian-vault/vulnerabilities/access-control.md +122 -0
  48. package/obsidian-vault/vulnerabilities/flash-loan-attack.md +66 -0
  49. package/obsidian-vault/vulnerabilities/oracle-manipulation.md +135 -0
  50. package/obsidian-vault/vulnerabilities/reentrancy.md +141 -0
  51. package/obsidian-vault/vulnerabilities/rust-unsafe-deserialization.md +128 -0
  52. package/obsidian-vault/vulnerabilities/solana-account-confusion.md +125 -0
  53. package/obsidian-vault/vulnerabilities/solana-close-account.md +141 -0
  54. package/obsidian-vault/vulnerabilities/solana-cpi-attacks.md +131 -0
  55. package/obsidian-vault/vulnerabilities/solana-signer-authorization.md +119 -0
  56. package/package.json +56 -0
  57. package/skills/audit-connect.md +385 -0
  58. package/skills/auditor.md +280 -0
  59. package/skills/exploit-generator.md +394 -0
  60. package/skills/novel-discovery.md +551 -0
  61. package/skills/test-generator.md +511 -0
@@ -0,0 +1,251 @@
1
+ # Ronin Bridge Exploit (2022)
2
+
3
+ **Date:** March 23, 2022
4
+ **Loss:** $625 million (173,600 ETH + 25.5M USDC)
5
+ **Type:** Validator Compromise / Multi-sig Attack
6
+ **Severity:** CRITICAL
7
+
8
+ ---
9
+
10
+ ## Summary
11
+
12
+ The Ronin Bridge was a cross-chain bridge connecting Ethereum to the Ronin sidechain (built for Axie Infinity). The attacker gained control of 5 out of 9 validator keys, allowing them to approve fraudulent withdrawals.
13
+
14
+ ---
15
+
16
+ ## Technical Details
17
+
18
+ ### Vulnerability Root Cause
19
+
20
+ The Ronin bridge used a **5-of-9 multi-signature scheme** for validating withdrawals. The attacker compromised:
21
+
22
+ 1. **4 validator keys** from Sky Mavis (Ronin operator)
23
+ 2. **1 validator key** from Axie DAO (governance validator)
24
+
25
+ With 5 of 9 keys, the attacker could create valid withdrawal proofs.
26
+
27
+ ### Attack Vector
28
+
29
+ ```solidity
30
+ // Simplified Ronin Bridge Logic
31
+ contract RoninBridge {
32
+ mapping(bytes32 => bool) public processedWithdrawals;
33
+ address[] public validators; // 9 validators
34
+ uint256 public constant VALIDATOR_THRESHOLD = 5;
35
+
36
+ function withdraw(
37
+ address recipient,
38
+ uint256 amount,
39
+ bytes memory signatures
40
+ ) external {
41
+ bytes32 withdrawalHash = keccak256(
42
+ abi.encode(recipient, amount, nonce)
43
+ );
44
+
45
+ require(!processedWithdrawals[withdrawalHash], "Already processed");
46
+
47
+ // Verify 5 of 9 validator signatures
48
+ require(
49
+ verifySignatures(withdrawalHash, signatures, validators),
50
+ "Invalid signatures"
51
+ );
52
+
53
+ processedWithdrawals[withdrawalHash] = true;
54
+
55
+ // Transfer tokens to attacker
56
+ IERC20(token).transfer(recipient, amount);
57
+ }
58
+ }
59
+ ```
60
+
61
+ ### Attack Sequence
62
+
63
+ ```
64
+ 1. Attacker gains control of 5 validator private keys
65
+ - 4 keys from Sky Mavis (compromised via social engineering/malware)
66
+ - 1 key from Axie DAO validator
67
+
68
+ 2. Attacker creates fraudulent withdrawal request:
69
+ - Recipient: attacker address
70
+ - Amount: 173,600 ETH + 25.5M USDC
71
+
72
+ 3. Attacker signs withdrawal with 5 compromised keys
73
+
74
+ 4. Bridge verifies signatures (5 of 9 = valid)
75
+
76
+ 5. Tokens transferred to attacker
77
+
78
+ 6. Attacker launders funds through Tornado Cash
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Why Standard Audits Missed This
84
+
85
+ | Audit Focus | What Was Missed |
86
+ |-------------|-----------------|
87
+ | Smart contract code | Off-chain key management |
88
+ | Signature verification | Validator selection/security |
89
+ | Reentrancy, overflow | Centralization of validator keys |
90
+ | Economic incentives | Single entity controlled 4/9 keys |
91
+
92
+ ---
93
+
94
+ ## Key Lessons
95
+
96
+ ### 1. Validator Centralization Risk
97
+ ```
98
+ PROBLEM: 4 of 9 validators controlled by single entity (Sky Mavis)
99
+ SOLUTION: Distribute validators across independent entities/jurisdictions
100
+ ```
101
+
102
+ ### 2. Threshold Selection
103
+ ```
104
+ PROBLEM: 5/9 = 55.5% threshold too low for high-value bridge
105
+ SOLUTION: Higher thresholds (e.g., 7/9 = 77.8%) for large withdrawals
106
+ ```
107
+
108
+ ### 3. Withdrawal Rate Limits
109
+ ```
110
+ PROBLEM: No daily/monthly withdrawal caps
111
+ SOLUTION: Implement time-based limits with emergency escalation
112
+ ```
113
+
114
+ ### 4. Multi-Sig Upgrade Mechanism
115
+ ```
116
+ PROBLEM: Validator set could not be changed quickly
117
+ SOLUTION: Emergency multi-sig to rotate compromised validators
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Exploit Code (Simplified PoC)
123
+
124
+ ```solidity
125
+ // Foundry PoC for Ronin-style attack
126
+ contract RoninExploitTest is Test {
127
+ RoninBridge bridge;
128
+ address[9] validators;
129
+ address attacker = makeAddr("attacker");
130
+
131
+ function test_validatorCompromiseAttack() public {
132
+ // Setup: Deploy bridge with 9 validators, 5 threshold
133
+ bridge = new RoninBridge(validators, 5);
134
+
135
+ // Fund bridge
136
+ deal(address(bridge), 200_000 ether);
137
+
138
+ // Attacker controls 5 validators
139
+ address[5] memory compromisedValidators = [
140
+ validators[0], validators[1], validators[2],
141
+ validators[3], validators[4]
142
+ ];
143
+
144
+ // Create withdrawal hash
145
+ bytes32 withdrawalHash = keccak256(
146
+ abi.encode(attacker, 173_600 ether, block.number)
147
+ );
148
+
149
+ // Sign with 5 compromised keys
150
+ bytes memory signatures = createSignatures(
151
+ withdrawalHash,
152
+ compromisedValidators
153
+ );
154
+
155
+ // Execute fraudulent withdrawal
156
+ uint256 balanceBefore = attacker.balance;
157
+ bridge.withdraw(attacker, 173_600 ether, signatures);
158
+ uint256 balanceAfter = attacker.balance;
159
+
160
+ // Verify attack succeeded
161
+ assertEq(balanceAfter - balanceBefore, 173_600 ether);
162
+ console.log("Attack successful: drained 173,600 ETH");
163
+ }
164
+
165
+ function createSignatures(
166
+ bytes32 hash,
167
+ address[5] memory signers
168
+ ) internal pure returns (bytes memory) {
169
+ // Simplified signature aggregation
170
+ // In reality, would use ECDSA signatures
171
+ return abi.encodePacked(hash, signers);
172
+ }
173
+ }
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Detection Checklist for Auditors
179
+
180
+ When auditing bridges, verify:
181
+
182
+ - [ ] Validator set is sufficiently decentralized
183
+ - [ ] No single entity controls threshold number of validators
184
+ - [ ] Withdrawal rate limits exist (daily/monthly caps)
185
+ - [ ] Emergency pause mechanism with multi-sig
186
+ - [ ] Validator rotation mechanism exists
187
+ - [ ] Slashing conditions for malicious validators
188
+ - [ ] Time delays for large withdrawals
189
+ - [ ] Multi-chain confirmation requirements
190
+
191
+ ---
192
+
193
+ ## Invariants That Should Have Been Tested
194
+
195
+ ```solidity
196
+ // INVARIANT: No single entity should control threshold validators
197
+ function invariant_validatorDecentralization() public view {
198
+ mapping(address => uint256) entityValidators;
199
+
200
+ for (uint i = 0; i < validators.length; i++) {
201
+ address entity = getValidatorEntity(validators[i]);
202
+ entityValidators[entity]++;
203
+ }
204
+
205
+ for (address entity : allEntities) {
206
+ assert(
207
+ entityValidators[entity] < THRESHOLD,
208
+ "Single entity controls threshold"
209
+ );
210
+ }
211
+ }
212
+
213
+ // INVARIANT: Daily withdrawals should not exceed limit
214
+ function invariant_dailyWithdrawalLimit() public {
215
+ uint256 dailyTotal = getWithdrawalsToday();
216
+ assert(dailyTotal <= MAX_DAILY_WITHDRAWAL);
217
+ }
218
+
219
+ // INVARIANT: Large withdrawals require additional confirmation
220
+ function invariant_largeWithdrawalDelay() public {
221
+ if (withdrawalAmount > LARGE_WITHDRAWAL_THRESHOLD) {
222
+ assert(block.timestamp >= withdrawalRequestTime + DELAY);
223
+ }
224
+ }
225
+ ```
226
+
227
+ ---
228
+
229
+ ## Aftermath
230
+
231
+ | Action | Result |
232
+ |--------|--------|
233
+ | Bridge paused | March 23, 2022 |
234
+ | FBI investigation | Attributed to Lazarus Group (North Korea) |
235
+ | $30M recovered | From USDC freeze |
236
+ | $625M+ lost | Remainder in Tornado Cash |
237
+ | Sky Mavis raise | Raised $150M to rebuild |
238
+
239
+ ---
240
+
241
+ ## Related Exploits
242
+ - [[wormhole-2022]] - Similar signature verification bypass
243
+ - [[nomad-2022]] - Replay attack on merkle proofs
244
+ - [[harmony-2022]] - Multi-sig compromise
245
+
246
+ ---
247
+
248
+ ## References
249
+ - [Ronin Bridge Post-Mortem](https://roninblockchain.substack.com/p/ronin-network-validator-compromise)
250
+ - [Chainalysis Report](https://blog.chainalysis.com/reports/north-korea-lazarus-group-cryptocurrency-thefts-2022-update/)
251
+ - [FBI Press Release](https://www.justice.gov/opa/pr/north-korean-lazarus-group-members-charged-conspiring-launder-2021-cyberheist-proceeds)
@@ -0,0 +1,284 @@
1
+ # Wormhole Bridge Exploit (2022)
2
+
3
+ **Date:** February 2, 2022
4
+ **Loss:** $325 million (120,000 wETH)
5
+ **Type:** Signature Verification Bypass
6
+ **Severity:** CRITICAL
7
+
8
+ ---
9
+
10
+ ## Summary
11
+
12
+ The Wormhole bridge (Solana ↔ Ethereum) was exploited due to a bug in the signature verification logic. The attacker was able to create valid withdrawal proofs without proper validator signatures.
13
+
14
+ ---
15
+
16
+ ## Technical Details
17
+
18
+ ### Vulnerability Root Cause
19
+
20
+ The vulnerability was in the **signature verification function** on the Solana side. The code failed to properly verify that the validator signatures matched the withdrawal data.
21
+
22
+ ```rust
23
+ // Simplified Wormhole Guardian Logic (VULNERABLE)
24
+ fn verify_signatures(
25
+ message: &Message,
26
+ signatures: &[Signature],
27
+ guardians: &[Pubkey]
28
+ ) -> Result<()> {
29
+ // BUG: Function verified signatures were valid
30
+ // But did NOT verify signatures were for THIS message
31
+
32
+ for (sig, guardian) in signatures.iter().zip(guardians.iter()) {
33
+ // Checked: Is this a valid signature from this guardian?
34
+ // Missing: Is this signature for THIS specific message?
35
+ if !verify_ed25519(sig, guardian, message) {
36
+ return Err(InvalidSignature);
37
+ }
38
+ }
39
+
40
+ Ok(())
41
+ }
42
+ ```
43
+
44
+ ### The Actual Bug
45
+
46
+ In the real code, the issue was more subtle. The guardian set verification had a logic error where:
47
+
48
+ 1. The code checked if signatures were from valid guardians
49
+ 2. But did not properly bind the signatures to the specific withdrawal hash
50
+ 3. This allowed reuse of signatures or creation of fake proofs
51
+
52
+ ### Attack Sequence
53
+
54
+ ```
55
+ 1. Attacker identifies signature verification bug
56
+
57
+ 2. Creates fraudulent withdrawal instruction:
58
+ - Amount: 120,000 wETH
59
+ - Recipient: attacker-controlled address on Ethereum
60
+
61
+ 3. Bypasses signature verification:
62
+ - Either reuses old valid signatures
63
+ - Or creates signatures that verify without guardian keys
64
+
65
+ 4. Submits proof to Wormhole contract
66
+
67
+ 5. Contract verifies (buggy) signatures - PASSES
68
+
69
+ 6. 120,000 wETH minted and sent to attacker
70
+
71
+ 7. Attacker bridges to Ethereum and cashes out
72
+ ```
73
+
74
+ ---
75
+
76
+ ## Exploit Code Analysis
77
+
78
+ ### Vulnerable Pattern
79
+
80
+ ```rust
81
+ // BEFORE FIX - Vulnerable
82
+ fn post_vaa(
83
+ &mut self,
84
+ vaa: Vec<u8>,
85
+ ) -> Result<()> {
86
+ let parsed_vaa = parse_vaa(&vaa)?;
87
+
88
+ // BUG: Signature verification didn't properly bind to VAA body
89
+ verify_signatures(
90
+ &parsed_vaa.signatures,
91
+ &self.guardian_set
92
+ )?;
93
+
94
+ // Process withdrawal based on unverified VAA
95
+ self.process_withdrawal(&parsed_vaa.body)?;
96
+
97
+ Ok(())
98
+ }
99
+
100
+ // AFTER FIX - Correct
101
+ fn post_vaa_fixed(
102
+ &mut self,
103
+ vaa: Vec<u8>,
104
+ ) -> Result<()> {
105
+ let parsed_vaa = parse_vaa(&vaa)?;
106
+
107
+ // FIX: Hash includes full VAA body
108
+ let message_hash = keccak256(&parsed_vaa.body);
109
+
110
+ // Signatures must match THIS specific hash
111
+ verify_signatures_bound_to_hash(
112
+ &parsed_vaa.signatures,
113
+ &self.guardian_set,
114
+ &message_hash // <-- Added hash binding
115
+ )?;
116
+
117
+ self.process_withdrawal(&parsed_vaa.body)?;
118
+ Ok(())
119
+ }
120
+ ```
121
+
122
+ ---
123
+
124
+ ## Foundry PoC Template
125
+
126
+ ```solidity
127
+ // Simplified PoC for Wormhole-style signature bypass
128
+ contract WormholeExploitTest is Test {
129
+ WormholeBridge bridge;
130
+ address[] guardians;
131
+
132
+ function test_signatureVerificationBypass() public {
133
+ // Setup: Bridge with guardian set
134
+ guardians = createGuardians(19);
135
+ bridge = new WormholeBridge(guardians, 13); // 13/19 threshold
136
+
137
+ // Fund bridge
138
+ deal(address(bridge.weth()), 200_000 ether);
139
+
140
+ // Create withdrawal message
141
+ Withdrawal memory withdrawal = Withdrawal({
142
+ recipient: address(this),
143
+ amount: 120_000 ether,
144
+ chainId: 1,
145
+ nonce: 1
146
+ });
147
+
148
+ // BUG: Create signatures that verify but aren't bound to message
149
+ bytes memory fakeSignatures = createUnboundSignatures();
150
+
151
+ // Submit fraudulent VAA (Verifiable Action Approval)
152
+ bytes memory vaa = abi.encode(withdrawal, fakeSignatures);
153
+
154
+ uint256 balanceBefore = address(this).balance;
155
+
156
+ // This should fail but doesn't due to bug
157
+ bridge.postVAA(vaa);
158
+
159
+ uint256 balanceAfter = address(this).balance;
160
+
161
+ // Verify exploit succeeded
162
+ assertEq(balanceAfter - balanceBefore, 120_000 ether);
163
+ console.log("Wormhole exploit successful: 120,000 ETH drained");
164
+ }
165
+
166
+ function createUnboundSignatures() internal pure returns (bytes memory) {
167
+ // Simulates creating signatures that verify
168
+ // but aren't properly bound to message hash
169
+ return new bytes(65 * 13); // 13 signatures
170
+ }
171
+ }
172
+ ```
173
+
174
+ ---
175
+
176
+ ## Why This Was Missed
177
+
178
+ | Audit Gap | Explanation |
179
+ |-----------|-------------|
180
+ | Assumed crypto correctness | Auditors assumed signature lib was correct |
181
+ | Focus on business logic | Didn't deep-dive into crypto primitives |
182
+ | Cross-chain complexity | Solana + Ethereum made review harder |
183
+ | Time pressure | Rapid deployment for competitive reasons |
184
+
185
+ ---
186
+
187
+ ## Key Lessons for Auditors
188
+
189
+ ### 1. Never Assume Crypto Correctness
190
+ ```
191
+ ALWAYS verify:
192
+ - Signature binding to specific message hash
193
+ - Nonce/replay protection
194
+ - Chain ID inclusion
195
+ - Domain separation
196
+ ```
197
+
198
+ ### 2. Cross-Chain State Consistency
199
+ ```
200
+ VERIFY:
201
+ - State on Chain A matches state on Chain B
202
+ - Wrapped supply = locked supply
203
+ - No double-spend vectors
204
+ ```
205
+
206
+ ### 3. Guardian/Validator Security
207
+ ```
208
+ CHECK:
209
+ - Guardian key management
210
+ - Threshold selection rationale
211
+ - Guardian rotation mechanism
212
+ - Slashing for malicious guardians
213
+ ```
214
+
215
+ ---
216
+
217
+ ## Detection Checklist
218
+
219
+ When auditing bridges with signature verification:
220
+
221
+ - [ ] Signatures are bound to specific message hash
222
+ - [ ] Message hash includes: amount, recipient, nonce, chainId
223
+ - [ ] Replay protection implemented (nonce or unique ID)
224
+ - [ ] Domain separation prevents cross-chain replay
225
+ - [ ] Guardian set is immutable or has secure rotation
226
+ - [ ] Threshold is appropriate for value at risk
227
+ - [ ] Rate limits on large withdrawals
228
+ - [ ] Emergency pause mechanism
229
+
230
+ ---
231
+
232
+ ## Invariants to Test
233
+
234
+ ```solidity
235
+ // INVARIANT: Every withdrawal must have valid guardian signatures
236
+ function invariant_withdrawalSignatures() public {
237
+ for (uint i = 0; i < withdrawalCount; i++) {
238
+ Withdrawal memory w = withdrawals[i];
239
+ assertTrue(
240
+ verifySignaturesBoundToMessage(w.signatures, w.hash),
241
+ "Signature not bound to message"
242
+ );
243
+ }
244
+ }
245
+
246
+ // INVARIANT: Total wrapped supply equals locked supply
247
+ function invariant_wrappedSupply() public view {
248
+ assertEq(
249
+ wrappedToken.totalSupply(),
250
+ lockedToken.balanceOf(address(bridge))
251
+ );
252
+ }
253
+
254
+ // INVARIANT: No duplicate nonces
255
+ function invariant_nonceUniqueness() public {
256
+ // Should revert if any nonce is reused
257
+ }
258
+ ```
259
+
260
+ ---
261
+
262
+ ## Aftermath
263
+
264
+ | Action | Result |
265
+ |--------|--------|
266
+ | Bridge paused | February 2, 2022 |
267
+ | Jump Crypto bailout | Covered $325M loss |
268
+ | Bridge reopened | February 23, 2022 |
269
+ | Security audit | Multiple firms engaged |
270
+ | Code open sourced | Full transparency |
271
+
272
+ ---
273
+
274
+ ## Related Exploits
275
+ - [[ronin-2022]] - Validator compromise
276
+ - [[nomad-2022]] - Replay attack
277
+ - [[multichain-2023]] - Similar bridge exploit
278
+
279
+ ---
280
+
281
+ ## References
282
+ - [Wormhole Post-Mortem](https://wormhole.com/post-mortem)
283
+ - [Neodyme Analysis](https://neodyme.io/en/blog/wormhole)
284
+ - [OtterSec Report](https://osec.io/blog/wormhole-exploit)
@@ -0,0 +1,77 @@
1
+ # Failed Hypothesis Template
2
+
3
+ tags: #failed-hypothesis #template #learning
4
+
5
+ ---
6
+
7
+ ## Hypothesis
8
+ [One sentence describing the attempted attack]
9
+
10
+ ## Contract
11
+ [Nome do Contrato] — [Address if deployed]
12
+
13
+ ---
14
+
15
+ ## What Was Tested
16
+ [Description of the attack vector that was attempted]
17
+
18
+ ## Attack Steps Attempted
19
+ ```
20
+ 1. [Step taken]
21
+ 2. [Step taken]
22
+ 3. [Step taken]
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Why It Failed
28
+
29
+ ### Technical Reason
30
+ [The specific code, check, or condition that prevented the attack]
31
+
32
+ ### Code Reference
33
+ ```solidity
34
+ // The line or function that blocked the attack
35
+ ```
36
+
37
+ ### Root Cause Category
38
+ - [ ] Validation check present
39
+ - [ ] Access control blocked
40
+ - [ ] State transition invalid
41
+ - [ ] Economic assumptions wrong
42
+ - [ ] Timing constraints
43
+ - [ ] Protocol design prevents it
44
+ - [ ] Other: [specify]
45
+
46
+ ---
47
+
48
+ ## Lessons Learned
49
+
50
+ ### About This Contract
51
+ [What this tells us about the contract's security]
52
+
53
+ ### Pattern Recognition
54
+ [What to look for in future audits — "this pattern prevents X"]
55
+
56
+ ### Alternative Angles
57
+ [Ways this could still be exploitable or related attack vectors to try]
58
+
59
+ ---
60
+
61
+ ## Related Hypotheses
62
+ - [[hypotheses/]] — Successful hypothesis on same contract
63
+ - [[attack-patterns/]] — Pattern this relates to
64
+
65
+ ---
66
+
67
+ ## Metadata
68
+ - **Date:** [When tested]
69
+ - **Auditor:** [Name]
70
+ - **Time Invested:** [How long spent on this hypothesis]
71
+ - **Confidence Before:** [High/Medium/Low]
72
+ - **Confidence After:** [Confirmed refuted]
73
+
74
+ ---
75
+
76
+ ## Notes
77
+ [Any additional observations, traces, or context]
@@ -0,0 +1,43 @@
1
+ # Hypothesis Template
2
+
3
+ tags: #hypothesis #template
4
+
5
+ ---
6
+
7
+ ## Contract
8
+ [Contract name and address if deployed]
9
+
10
+ ## Hypothesis
11
+ [One sentence: IF [condition] THEN [consequence]]
12
+
13
+ ## Attack Pattern
14
+ [Which pattern does this relate to? Link to attack-patterns/]
15
+
16
+ ## Preconditions
17
+ - [ ] Condition 1
18
+ - [ ] Condition 2
19
+
20
+ ## Attack Steps
21
+ ```
22
+ 1.
23
+ 2.
24
+ 3.
25
+ ```
26
+
27
+ ## Expected Outcome
28
+ [What happens if hypothesis is correct?]
29
+
30
+ ## Test Strategy
31
+ [How to test this hypothesis in Foundry?]
32
+
33
+ ## Result
34
+ - [ ] Confirmed — vulnerability exists
35
+ - [ ] Refuted — not exploitable
36
+ - [ ] Partial — exists but limited impact
37
+
38
+ ## Notes
39
+ [Observations during testing]
40
+
41
+ ## Links
42
+ - [[vulnerabilities/]]
43
+ - [[attack-patterns/]]