bug-bounty-intelligence-mcp 1.0.5 → 1.2.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.
package/BENCHMARK.md CHANGED
@@ -1,174 +1,174 @@
1
- # Benchmark: Bug Bounty Intelligence vs Slither
2
-
3
- **Target protocol:** 3FLabs/grunt — leveraged strategies for on-chain funds
4
- **Protocol type:** ERC-4626/ERC-7540 vaults + Morpho lending + flash loan requests
5
- **Scope:** `src/` (218 Solidity files)
6
- **Slither version:** 0.10.x
7
- **Date:** 2026-07-20
8
-
9
- ---
10
-
11
- ## TL;DR
12
-
13
- | Metric | Slither | Bug Bounty Intelligence |
14
- |--------|---------|------------------------|
15
- | "High" findings reported | 27 | 0 |
16
- | True positives (real bugs) | 0 | 0 |
17
- | False positives | 27 (100%) | 0 |
18
- | Out-of-scope library noise | 24 (89%) | 0 |
19
- | Signals requiring human review | n/a | 17 |
20
- | Reading time to triage all "Highs" | ~4 hours | ~15 min |
21
-
22
- **Slither false positive rate on this codebase: 100%.**
23
-
24
- ---
25
-
26
- ## Test setup
27
-
28
- We ran Slither on the full repo (including `lib/`), and Bug Bounty Intelligence on `src/` only. The scope for any real audit is `src/` — dependencies in `lib/` are battle-tested third-party code that has its own audit history.
29
-
30
- ---
31
-
32
- ## Slither's 27 "High" findings — breakdown
33
-
34
- ### Group A: 24 findings in `lib/solady/` (out of scope)
35
-
36
- Slither flagged 24 High-severity issues, all in the `lib/solady/` dependency:
37
-
38
- - 5x `incorrect-exp` — Solady uses XOR (`^`) for bitwise operations, not exponentiation. Slither confuses the two.
39
- - 19x `incorrect-shift` — Solady uses `<<` / `>>` inside assembly blocks. Slither's detector fires on these but they are intentional and correct.
40
-
41
- **Why these are not bugs:**
42
-
43
- Solady is one of the most audited Solidity libraries in existence, used by hundreds of protocols. Its math implementations deliberately use low-level bit operations for gas efficiency. Slither's `incorrect-exp` and `incorrect-shift` detectors are known to produce false positives on Solady. Every human auditor knows to ignore these. Slither does not.
44
-
45
- **Example:**
46
-
47
- ```
48
- incorrect-shift | FixedPointMathLib.lnWad(int256) (lib/solady/src/utils/FixedPointMathLib.sol#269-341)
49
- contains an incorrect shift operation: ...
50
- ```
51
-
52
- This is in `lib/solady/`, a third-party library. It is out of scope for any 3FLabs audit.
53
-
54
- **Update:** while triaging these, we noticed a related pattern on the same `lib/solady` code:
55
- `divide-before-multiply` fired 38 times on `FixedPointMathLib`'s `fullMulDivUnchecked`, `cbrt`,
56
- `invMod`, `rpow`, and `cbrtWad`. We initially described all 38 as the same false-positive class
57
- (divided variable fully reassigned before the multiply) and reported it upstream —
58
- [crytic/slither#3039](https://github.com/crytic/slither/issues/3039). That was an overclaim on our
59
- part. A maintainer merged a fix for the specific reassignment pattern we described
60
- ([crytic/slither#3040](https://github.com/crytic/slither/pull/3040), not yet in a PyPI release as
61
- of 2026-08-01), and re-testing against the merged code ourselves shows it correctly resolves 11 of
62
- the 38 (down to 27 remaining on this file). The other 27 keep the divided variable in the same
63
- expression rather than through a clean reassignment, which is a different pattern this fix
64
- correctly leaves untouched — we haven't yet re-analyzed whether those are genuine false positives
65
- too or something else. Filed as a lesson: verify a fix against the actual code before describing
66
- it as resolving the full scope of what you reported.
67
-
68
- ### Group B: 3 findings in `src/` — all false positives
69
-
70
- Slither flagged 3 uses of `safeTransferFrom(offer.maker, ...)` as "arbitrary from in transferFrom":
71
-
72
- ```
73
- arbitrary-send-erc20 | Request.consume() uses arbitrary from in transferFrom:
74
- _asset().safeTransferFrom(offer.maker, address(this), ptAmount)
75
- ```
76
-
77
- **Why this is not a bug:**
78
-
79
- `offer.maker` is not arbitrary. The offer is validated via EIP-712 signature before the transfer (`_validateOffer(offer, signature)` is called on line 421). The maker explicitly signed the offer, authorizing exactly this transfer of exactly this amount. Additionally, `consume()` is gated by `onlyOwnerOrRoles(_ROLE_CONSUMER)` — only trusted consumers can call it.
80
-
81
- This is a correct and standard EIP-712 off-chain order pattern. Slither has no understanding of EIP-712 and cannot reason about signature-based authorization.
82
-
83
- ---
84
-
85
- ## What Bug Bounty Intelligence flags instead
86
-
87
- After filtering to `src/` and applying Al-Mizaan validation gates, we identified **17 signals requiring human review** — none rising to a confirmed finding:
88
-
89
- | Category | Count | Description |
90
- |----------|-------|-------------|
91
- | `unsafe_keyword` | 15 | Explicit `forge-lint: disable-next-line(unsafe-typecast)` annotations — developer acknowledged unsafe casts. Require review for truncation risk. |
92
- | `delegatecall` | 2 | `MorphoFlashLoanRequest.execute()` delegatecalls to whitelisted scripts. By design — whitelist check present. |
93
-
94
- **What we do not flag:**
95
- - Library code in `lib/` (out of scope)
96
- - EIP-712 signed transfers (intentional pattern, not a vulnerability)
97
- - Standard Solady bit operations (well-audited library behavior)
98
-
99
- ---
100
-
101
- ## Al-Mizaan filtering — why the 17 signals do not become findings
102
-
103
- The 15 `unsafe_keyword` signals (explicit forge-lint disables) were put through Al-Mizaan's reachability chain:
104
-
105
- 1. **Code** — read the actual casts in `LibTokenController.sol`, `TokenController.sol`, and `PositionManagerLP.sol`
106
- 2. **Reachability** — are the truncated values reachable by an untrusted caller?
107
- 3. **Threat model** — who triggers these paths? In all cases, the entry points are role-gated (owner, ROLE_CONSUMER, ROLE_MANAGER)
108
- 4. **Invariant** — does the truncation break any accounting invariant?
109
-
110
- Verdict: The typecasts are `uint256 → uint128` in share accounting. The values come from internal calculations that are capped by deposit limits. Overflow requires either extremely large TVL or a role-gated actor. **Trusted actor as sole trigger → ELIMINATE.**
111
-
112
- The 2 `delegatecall` signals: `MorphoFlashLoanRequest` maintains an explicit `isScriptWhitelisted` mapping. Only the owner can whitelist. **Trusted actor (owner) as sole attacker → ELIMINATE.**
113
-
114
- **Result: 0 confirmed findings.** This matches the expected difficulty level of a mature protocol with prior audits.
115
-
116
- ---
117
-
118
- ## Why Slither's false positive rate matters
119
-
120
- A 100% false positive rate on High findings is not an edge case. It happens because:
121
-
122
- 1. **No scope awareness** — Slither scans everything, including dependencies. A real audit scopes to `src/` only.
123
- 2. **No protocol context** — Slither cannot distinguish between an arbitrary `transferFrom` and an EIP-712-authorized one.
124
- 3. **No library knowledge** — Solady's assembly patterns trigger false positives on multiple detectors.
125
-
126
- For a developer running Slither for the first time, triaging 27 "High" findings (all false positives) takes hours. For a developer using Bug Bounty Intelligence, the 17 signals that remain after scope filtering take 15 minutes to review.
127
-
128
- ---
129
-
130
- ## When Slither IS useful
131
-
132
- Slither is best used as a first-pass tool before human review, with explicit exclusions:
133
-
134
- ```bash
135
- slither src/ --exclude incorrect-exp,incorrect-shift --filter-paths "lib/"
136
- ```
137
-
138
- After filtering, Slither's Medium and Low findings become more useful starting points.
139
-
140
- Bug Bounty Intelligence is designed to do this filtering for you, and adds protocol-context reasoning that static analysis cannot.
141
-
142
- ---
143
-
144
- ## Reproduce this benchmark
145
-
146
- The 3FLabs/grunt codebase is public at [github.com/3FLabs/grunt](https://github.com/3FLabs/grunt).
147
-
148
- To reproduce Slither's output:
149
- ```bash
150
- git clone https://github.com/3FLabs/grunt
151
- cd grunt
152
- pip install slither-analyzer
153
- slither . --json slither-output.json
154
- ```
155
-
156
- To use Bug Bounty Intelligence:
157
- ```bash
158
- npx -y bug-bounty-intelligence-mcp@latest
159
- ```
160
-
161
- Then in your MCP client:
162
- ```
163
- scan_contract({ repo_url: "https://github.com/3FLabs/grunt", protocol_type: "LENDING" })
164
- ```
165
-
166
- ---
167
-
168
- ## About Bug Bounty Intelligence
169
-
170
- Pattern-aware from a corpus of 27,681 submitted Sherlock/Code4rena findings across 105 contests; acceptance-rate numbers (used by `list_vulnerability_patterns`) are limited to the 1,032 findings across 10 contests that could be exact-reconciled against contest outcomes (461 accepted) — see METHODOLOGY.md. Uses the Al-Mizaan v3 framework — a 7-gate validation chain (Code, Reachability, Threat-Model, Invariant, Protocol-Intent, Impact, Proof) — to filter signals into confirmed findings.
171
-
172
- **Cost:** $5 USDC on Base (eip155:8453) via x402.
173
- **Install:** `npx -y bug-bounty-intelligence-mcp@latest`
174
- **npm:** [npmjs.com/package/bug-bounty-intelligence-mcp](https://www.npmjs.com/package/bug-bounty-intelligence-mcp)
1
+ # Benchmark: Bug Bounty Intelligence vs Slither
2
+
3
+ **Target protocol:** 3FLabs/grunt — leveraged strategies for on-chain funds
4
+ **Protocol type:** ERC-4626/ERC-7540 vaults + Morpho lending + flash loan requests
5
+ **Scope:** `src/` (218 Solidity files)
6
+ **Slither version:** 0.10.x
7
+ **Date:** 2026-07-20
8
+
9
+ ---
10
+
11
+ ## TL;DR
12
+
13
+ | Metric | Slither | Bug Bounty Intelligence |
14
+ |--------|---------|------------------------|
15
+ | "High" findings reported | 27 | 0 |
16
+ | True positives (real bugs) | 0 | 0 |
17
+ | False positives | 27 (100%) | 0 |
18
+ | Out-of-scope library noise | 24 (89%) | 0 |
19
+ | Signals requiring human review | n/a | 17 |
20
+ | Reading time to triage all "Highs" | ~4 hours | ~15 min |
21
+
22
+ **Slither false positive rate on this codebase: 100%.**
23
+
24
+ ---
25
+
26
+ ## Test setup
27
+
28
+ We ran Slither on the full repo (including `lib/`), and Bug Bounty Intelligence on `src/` only. The scope for any real audit is `src/` — dependencies in `lib/` are battle-tested third-party code that has its own audit history.
29
+
30
+ ---
31
+
32
+ ## Slither's 27 "High" findings — breakdown
33
+
34
+ ### Group A: 24 findings in `lib/solady/` (out of scope)
35
+
36
+ Slither flagged 24 High-severity issues, all in the `lib/solady/` dependency:
37
+
38
+ - 5x `incorrect-exp` — Solady uses XOR (`^`) for bitwise operations, not exponentiation. Slither confuses the two.
39
+ - 19x `incorrect-shift` — Solady uses `<<` / `>>` inside assembly blocks. Slither's detector fires on these but they are intentional and correct.
40
+
41
+ **Why these are not bugs:**
42
+
43
+ Solady is one of the most audited Solidity libraries in existence, used by hundreds of protocols. Its math implementations deliberately use low-level bit operations for gas efficiency. Slither's `incorrect-exp` and `incorrect-shift` detectors are known to produce false positives on Solady. Every human auditor knows to ignore these. Slither does not.
44
+
45
+ **Example:**
46
+
47
+ ```
48
+ incorrect-shift | FixedPointMathLib.lnWad(int256) (lib/solady/src/utils/FixedPointMathLib.sol#269-341)
49
+ contains an incorrect shift operation: ...
50
+ ```
51
+
52
+ This is in `lib/solady/`, a third-party library. It is out of scope for any 3FLabs audit.
53
+
54
+ **Update:** while triaging these, we noticed a related pattern on the same `lib/solady` code:
55
+ `divide-before-multiply` fired 38 times on `FixedPointMathLib`'s `fullMulDivUnchecked`, `cbrt`,
56
+ `invMod`, `rpow`, and `cbrtWad`. We initially described all 38 as the same false-positive class
57
+ (divided variable fully reassigned before the multiply) and reported it upstream —
58
+ [crytic/slither#3039](https://github.com/crytic/slither/issues/3039). That was an overclaim on our
59
+ part. A maintainer merged a fix for the specific reassignment pattern we described
60
+ ([crytic/slither#3040](https://github.com/crytic/slither/pull/3040), not yet in a PyPI release as
61
+ of 2026-08-01), and re-testing against the merged code ourselves shows it correctly resolves 11 of
62
+ the 38 (down to 27 remaining on this file). The other 27 keep the divided variable in the same
63
+ expression rather than through a clean reassignment, which is a different pattern this fix
64
+ correctly leaves untouched — we haven't yet re-analyzed whether those are genuine false positives
65
+ too or something else. Filed as a lesson: verify a fix against the actual code before describing
66
+ it as resolving the full scope of what you reported.
67
+
68
+ ### Group B: 3 findings in `src/` — all false positives
69
+
70
+ Slither flagged 3 uses of `safeTransferFrom(offer.maker, ...)` as "arbitrary from in transferFrom":
71
+
72
+ ```
73
+ arbitrary-send-erc20 | Request.consume() uses arbitrary from in transferFrom:
74
+ _asset().safeTransferFrom(offer.maker, address(this), ptAmount)
75
+ ```
76
+
77
+ **Why this is not a bug:**
78
+
79
+ `offer.maker` is not arbitrary. The offer is validated via EIP-712 signature before the transfer (`_validateOffer(offer, signature)` is called on line 421). The maker explicitly signed the offer, authorizing exactly this transfer of exactly this amount. Additionally, `consume()` is gated by `onlyOwnerOrRoles(_ROLE_CONSUMER)` — only trusted consumers can call it.
80
+
81
+ This is a correct and standard EIP-712 off-chain order pattern. Slither has no understanding of EIP-712 and cannot reason about signature-based authorization.
82
+
83
+ ---
84
+
85
+ ## What Bug Bounty Intelligence flags instead
86
+
87
+ After filtering to `src/` and applying Al-Mizaan validation gates, we identified **17 signals requiring human review** — none rising to a confirmed finding:
88
+
89
+ | Category | Count | Description |
90
+ |----------|-------|-------------|
91
+ | `unsafe_keyword` | 15 | Explicit `forge-lint: disable-next-line(unsafe-typecast)` annotations — developer acknowledged unsafe casts. Require review for truncation risk. |
92
+ | `delegatecall` | 2 | `MorphoFlashLoanRequest.execute()` delegatecalls to whitelisted scripts. By design — whitelist check present. |
93
+
94
+ **What we do not flag:**
95
+ - Library code in `lib/` (out of scope)
96
+ - EIP-712 signed transfers (intentional pattern, not a vulnerability)
97
+ - Standard Solady bit operations (well-audited library behavior)
98
+
99
+ ---
100
+
101
+ ## Al-Mizaan filtering — why the 17 signals do not become findings
102
+
103
+ The 15 `unsafe_keyword` signals (explicit forge-lint disables) were put through Al-Mizaan's reachability chain:
104
+
105
+ 1. **Code** — read the actual casts in `LibTokenController.sol`, `TokenController.sol`, and `PositionManagerLP.sol`
106
+ 2. **Reachability** — are the truncated values reachable by an untrusted caller?
107
+ 3. **Threat model** — who triggers these paths? In all cases, the entry points are role-gated (owner, ROLE_CONSUMER, ROLE_MANAGER)
108
+ 4. **Invariant** — does the truncation break any accounting invariant?
109
+
110
+ Verdict: The typecasts are `uint256 → uint128` in share accounting. The values come from internal calculations that are capped by deposit limits. Overflow requires either extremely large TVL or a role-gated actor. **Trusted actor as sole trigger → ELIMINATE.**
111
+
112
+ The 2 `delegatecall` signals: `MorphoFlashLoanRequest` maintains an explicit `isScriptWhitelisted` mapping. Only the owner can whitelist. **Trusted actor (owner) as sole attacker → ELIMINATE.**
113
+
114
+ **Result: 0 confirmed findings.** This matches the expected difficulty level of a mature protocol with prior audits.
115
+
116
+ ---
117
+
118
+ ## Why Slither's false positive rate matters
119
+
120
+ A 100% false positive rate on High findings is not an edge case. It happens because:
121
+
122
+ 1. **No scope awareness** — Slither scans everything, including dependencies. A real audit scopes to `src/` only.
123
+ 2. **No protocol context** — Slither cannot distinguish between an arbitrary `transferFrom` and an EIP-712-authorized one.
124
+ 3. **No library knowledge** — Solady's assembly patterns trigger false positives on multiple detectors.
125
+
126
+ For a developer running Slither for the first time, triaging 27 "High" findings (all false positives) takes hours. For a developer using Bug Bounty Intelligence, the 17 signals that remain after scope filtering take 15 minutes to review.
127
+
128
+ ---
129
+
130
+ ## When Slither IS useful
131
+
132
+ Slither is best used as a first-pass tool before human review, with explicit exclusions:
133
+
134
+ ```bash
135
+ slither src/ --exclude incorrect-exp,incorrect-shift --filter-paths "lib/"
136
+ ```
137
+
138
+ After filtering, Slither's Medium and Low findings become more useful starting points.
139
+
140
+ Bug Bounty Intelligence is designed to do this filtering for you, and adds protocol-context reasoning that static analysis cannot.
141
+
142
+ ---
143
+
144
+ ## Reproduce this benchmark
145
+
146
+ The 3FLabs/grunt codebase is public at [github.com/3FLabs/grunt](https://github.com/3FLabs/grunt).
147
+
148
+ To reproduce Slither's output:
149
+ ```bash
150
+ git clone https://github.com/3FLabs/grunt
151
+ cd grunt
152
+ pip install slither-analyzer
153
+ slither . --json slither-output.json
154
+ ```
155
+
156
+ To use Bug Bounty Intelligence:
157
+ ```bash
158
+ npx -y bug-bounty-intelligence-mcp@latest
159
+ ```
160
+
161
+ Then in your MCP client:
162
+ ```
163
+ scan_contract({ repo_url: "https://github.com/3FLabs/grunt", protocol_type: "LENDING" })
164
+ ```
165
+
166
+ ---
167
+
168
+ ## About Bug Bounty Intelligence
169
+
170
+ Pattern-aware from a corpus of 56,657 submitted Sherlock findings across 212 measured contests plus the Code4rena contests crawled alongside them, acceptance-rate numbers (used by `list_vulnerability_patterns`) are limited to the 9,200 findings across 38 contests (35 Sherlock, 3 Code4rena) that could be exact-reconciled against contest outcomes (4,011 accepted), see METHODOLOGY.md. Uses the Al-Mizaan v3 framework, a 7-gate validation chain (Code, Reachability, Threat-Model, Invariant, Protocol-Intent, Impact, Proof), to filter signals into confirmed findings.
171
+
172
+ **Cost:** $5 USDC on Base (eip155:8453) via x402.
173
+ **Install:** `npx -y bug-bounty-intelligence-mcp@latest`
174
+ **npm:** [npmjs.com/package/bug-bounty-intelligence-mcp](https://www.npmjs.com/package/bug-bounty-intelligence-mcp)
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Abdellah Ouadoudi
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Abdellah Ouadoudi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.