Update bounty framework#299
Conversation
Replace the legacy "10% of value at risk" payout rule with the severity x likelihood matrix, fixed modifier list, worked examples, PoC requirements, and edge-case guidance. Scope stays on researcher-facing guidance; internal calibration and testing material is intentionally omitted.
Replace the single-sentence "may receive $0" note with explicit criteria: privileged-role-only exploit path, no demonstration that the role is reachable externally, and the bug does not fire in normal operation. Makes admin-only findings deterministically $0 instead of a discretionary judgment call.
Add a 5-step payout flow at the top so readers see the calculation path before the details. Pull rule-of-thumb one-liners into the severity and likelihood tables and surface the four severity decision rules directly under the table. Add a quick-checklist summary of modifiers alongside the full trigger table, a rough-intuition line near the matrix, and tighten several of the densest sentences. Same logic, less reading to reach a number.
|
Claude finished @clemsos's task in 2m 19s —— View job Code Review — Bug Bounty Program rewriteThis is a substantial and well-structured rewrite that replaces a vague "10% of value at risk" rule with a legible severity × likelihood × modifier framework. The structure is strong; flagging a typo, a terminology slip, and several places where the framework's rules could double-apply or are ambiguous.
Must-fix1. Typo — → "eligible". Fix this → 2.
(The "cross-chain" hyphenation on L125 is correct — §5 keeps that one hyphenated.) Framework consistency issuesThese are where the rules can collide with each other; worth tightening before this becomes the public contract with researchers. 3. Likelihood-downgrade criteria overlap with modifiers — risk of double-counting Two of the three likelihood-downgrade bullets (L48–52) describe the same conditions as two of the ×0.75 modifiers (L86–93):
A researcher (or reviewer) applying the framework literally could take both the tier drop and the ×0.75 for the same fact pattern — meaningfully shrinking the payout for the same underlying property. Recommend stating explicitly that a given real-world fact can only reduce payout through one channel (either likelihood downgrade OR a ×0.75 modifier, not both), or collapsing the overlap. Notably, the "Fee parameter drift" worked example (L117–121) applies Pausable + monitored as a modifier but does not downgrade likelihood from L3 — implicitly choosing the modifier path. Good choice, but the rule isn't stated. 4. S3's severity definition already includes "permanent freeze" (L27). The permanent pool freeze example (L123–129) takes S3 and applies the ×1.5 "permanently unrecoverable" modifier, yielding $22,500. The Either:
5. Rounding at exact halfway points is undefined L18: "Round to the nearest $500." The Fee parameter drift example lands exactly on $3,750 → $4,000 (L121). $3,750 is equidistant from $3,500 and $4,000. The worked example effectively commits to "round half up" but the rule doesn't say so. One-line fix: "Round to the nearest $500 (ties round up)." 6. Likelihood-tier floor is implicit L48–52 ("We reduce likelihood by one tier when any of the following apply…") — there are three triggers listed with
The second point matters because an L1/S1 bug dropping further would hit the floor-vs-zero distinction at L63–71. Smaller content nits7. Duplicate-report rule — what about after 7 days? L136: "A duplicate submitted within 7 days receives 10% of the original as a courtesy payment." Past 7 days is presumably $0 with no courtesy payment — worth saying so explicitly rather than leaving readers to infer. 8. "a pool" is ambiguous in the flash-loan example — L109: "drain up to 100% of a pool in a single transaction." If Relay segregates funds across multiple pools, this could trigger the Bounded damage pool ×0.5 modifier (L93). The example rules out modifiers (L113), so the intent is "a pool = the whole thing" — but a researcher reading the page might reasonably disagree. Consider "the protocol's funds" or "the depository" for unambiguity. 9. "The list is fixed" — L75 reads a bit cryptically on first pass. Suggest "Modifiers are drawn from the fixed list below — do not invent new ones." 10. "the original" — L136 "10% of the original" reads as "10% of the original payout" but could be parsed as "10% of the original report." Suggest "10% of the first report's payout." 11. Intro drops "circuit breakers and alarms" — the old page explained why the 10-minute value-at-risk window existed (monitoring + pausing auto-stops longer attacks). The new framework relies on monitoring implicitly (via "Pausable + monitored" modifier) but never surfaces that Relay actually runs this infra. A one-liner in the intro or a footnote would make the modifier less abstract to researchers. Style guide check (§5 terminology)
Callout length (L95–99): 5 lines, well under the §2.5 15-line cap. ✅ SummaryStrong rewrite — the framework is dramatically clearer than the old page and the worked examples land. The blockers are the typo and Review checklist
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
Claude finished @clemsos's task in 2m 53s —— View job Code Review — Bug Bounty Program rewrite (follow-up)Re-reviewed after the three recent commits (
Resolved from previous review
New issues in this pass1. Dash inconsistency at L48 Every other em-style break on this page uses 2. L8 scope line reads awkwardly Parsed at a glance it's ambiguous between "(the Relay stack), (protocol), and (services)" — three things — vs. "the Relay stack: protocol and services" — two things apposed to "stack". The commit message
Framework consistency — residual3. Admin-only rule: S1 classification vs. $0 eligibility is under-connected Two rules govern admin-only bugs and they land in different sections:
Read naively, S1 promises at least $500; the eligibility rule negates that for the admin-only subset. The resolution — S1 applies to admin-only bugs that also have an external path reaching the role, otherwise $0 — is inferrable but not stated. A one-line cross-reference from the S1 admin-only bullet back to the eligibility list (or vice versa) would make the page self-consistent without a reader having to stitch it together. 4. Pausable + monitored: when does the modifier actually apply? The Flash loan reentrancy example (L107–113) does not apply Both examples are the right call, but the implicit rule — "the modifier applies only when pause/monitoring materially reduces expected loss" — isn't spelled out. As written, L88 says the modifier applies whenever the contract "can be paused and active monitoring … is in place," which is a property of the deployment, not the bug. A researcher could reasonably claim ×0.75 for a single-tx flash loan exploit on a pausable contract. Worth tightening the trigger definition, e.g. "…monitoring is in place and would meaningfully reduce loss against this exploit." 5. Quick checklist "or" vs. stacking These are two separate modifiers each (per the full table), and L101 says modifiers stack — so a bug that's both hard to fix and hard to detect gets ×1.25 × ×1.25 = ×1.5625. The "or" in the checklist suggests a single pick. Minor, but if a researcher scans only the checklist they'll under-claim. Either use "and/or" or drop the "or" in favor of comma-separation ("×1.25 — hard to fix; hard to detect"). Still open from previous review (minor)These weren't addressed in the latest commits. None are blockers.
SummaryThe framework is now materially tighter than last pass — the overlap between likelihood downgrades and modifiers is gone, the rounding rule is explicit, and the permanently-unrecoverable callout removes the biggest ambiguity on freeze bugs. Blockers before merge: just the L48 dash and the L8 rewording. Items #3 and #4 are worth a look because they'll come up in actual researcher disputes; the rest are nice-to-haves. Review checklist
|
|
Claude finished @clemsos's task in 2m 0s —— View job Code Review — Bug Bounty Program rewrite (follow-up)Thanks for the thorough pass on the prior review — nearly every item is resolved. One new inconsistency was introduced in the flash-loan example, plus two small nits. Prior review items — resolution
New issue introduced1. Flash-loan example now mismatches its own severity label — security/bounties.mdx:109-113 The "a pool" ambiguity was fixed by softening the description, but the softening broke the S4 classification: S4 is defined on L26 as "Total fund theft or protocol insolvency with no time to react." — the example description now says "some," which is not "total." A researcher mapping this example back to the rubric will land on S3 ("Large-scale fund theft … Requires some setup, but fast once triggered") or even S2, not S4. Two clean fixes:
Smaller nits2. Justification for the freeze-example downgrade doesn't match the stated rule — security/bounties.mdx:128 The framework rule at L48 is "reduce likelihood by one tier … when the exploit freezes rather than steals." That rule cleanly applies to this example. But the example justifies the downgrade with a different reason: "No profit motive and pays to execute" isn't a trigger in the framework (the "High attacker cost" ×0.75 modifier captures attacker cost, not a likelihood downgrade). A researcher reading this may infer there's an unwritten rule. Cleaner to cite the rule that actually applies: "downgraded one tier from L3 because the exploit freezes rather than steals." 3. Stray hyphen where an em-dash is used elsewhere — security/bounties.mdx:48 Everywhere else on this page the Style / terminology
SummaryStrong iteration — the framework coherence items from the previous review are now in good shape. The only blocker-ish item is the flash-loan example's description-vs-severity mismatch (#1); the other two are style polish. Once #1 is reconciled, this reads as a clean, self-consistent researcher contract. Review checklist
|
|
Claude finished @clemsos's task in 2m 5s —— View job Code Review — Bug Bounty Program rewrite (follow-up)Re-reviewed after the latest commit (
Fixes in this commit
Still outstanding from the previous review1. Flash-loan example: description vs severity label still mismatched — security/bounties.mdx:109-111 S4's definition on L26 is "Total fund theft or protocol insolvency with no time to react." — "some" does not map to "total." The description and severity label point at different tiers; a researcher using this example as a calibration anchor will either under- or over-claim. Simplest fix: restore the "total" semantics in the description ("drain the depository in a single transaction") so it matches S4. 2. Freeze-example downgrade cites an unwritten rule — security/bounties.mdx:128 The framework rule at L48 says the downgrade trigger is "the exploit freezes rather than steals" — which is exactly this example. "No profit motive / pays to execute" isn't a stated rule; cost-to-exploit is captured by the High attacker cost ×0.75 modifier, not a likelihood tier shift. Reword to cite the actual rule: "downgraded one tier from L3 because the exploit freezes rather than steals." 3. Stray hyphen where em-dash is used elsewhere — security/bounties.mdx:48 Every other parenthetical dash on this page is Minor — still open from the second review4. L8 scope line parses ambiguously — security/bounties.mdx:8 Still reads as three things vs. two — the commit title Style / terminology
SummaryThe single commit since last review was a correctness fix for MDX rendering — clean. The three items from the 14:54:43Z pass remain and are the last blockers before this page reads as a fully self-consistent researcher contract: (1) flash-loan example description/severity reconciliation, (2) L128 freeze-downgrade justification, (3) L48 em-dash. L8 wording from the earlier pass is a nice-to-have. Review checklist
|
|
Claude finished @clemsos's task in 2m 4s —— View job Code Review — Bug Bounty Program rewrite (follow-up)Re-reviewed after the latest two commits (
Blockers from previous review — all resolved
Still open (minor, nice-to-haves — not blockers)1. The two worked examples make the right call (flash-loan at L107–113 correctly skips the ×0.75 because a single-tx exploit finishes before any pause can bite; fee drift at L115–121 correctly applies it). But the written trigger — "Contract can be paused and active monitoring with sub-5-minute response is in place" — is a property of the deployment. A researcher reading only the trigger could claim ×0.75 on a single-tx flash-loan because the contract is pausable. Tightening to something like "…monitoring is in place and would meaningfully reduce loss against this specific exploit" would make the implicit rule explicit. 2. Quick checklist "or" vs. stacking — security/bounties.mdx:75-78 The full table lists these as two separate modifiers each, and L101 says modifiers stack — so a bug that is both hard to fix and hard to detect should get ×1.25 × ×1.25 = ×1.5625. The "or" suggests a single pick. A researcher who skims only the checklist will under-claim. Either "and/or" or semicolon-separation ("×1.25 — hard to fix; hard to detect") would be clearer. 3. S1 admin-only vs. $0 eligibility — still a bit disconnected — security/bounties.mdx:36 and L61-63 Two rules govern admin-only bugs and land in different sections:
The resolution is inferrable (S1 applies when there's also an external path reaching the role; otherwise $0), but it isn't stated. A one-line cross-reference from the S1 admin-only bullet back to the eligibility list would self-contain the page. Not a blocker — the rules are correct, just separated. 4. S3 "permanent freeze" + ×1.5 modifier — example doesn't spell out why both apply — security/bounties.mdx:127-129 The Style / terminology
SummaryThe framework is now clean: no overlap between likelihood downgrades and modifiers, rounding rule is explicit, permanent-unrecoverable-vs-severity distinction is handled by the Info callout, and all three worked examples cite their rules correctly. Ready to merge from a content-consistency standpoint. The four items above are polish-tier items worth a follow-up but not a blocker. Review checklist
|
|
Claude finished @clemsos's task in 1m 50s —— View job Code Review — Bug Bounty Program rewrite (follow-up)Re-reviewed after the latest two commits (
Prior review items — resolution
Remaining items (not blockers)1. Quick checklist inconsistency — security/bounties.mdx:76-77 The ×1.25 line was changed from "or" to "/" to hint at stackability: Two reads:
Either apply the same change to ×0.75 ( 2. Permanent-freeze example doesn't spell out why the freeze is unrecoverable — security/bounties.mdx:127-129 The Half-sentence fix: "…Permanently unrecoverable (×1.5) — pool accounting has no pause or upgrade path…". This mirrors the flash-loan example at L113 which cites the specific reason ("funds laundered in the same tx before any response is possible"). Style / terminology
SummaryThe page is mergeable. The admin-only + monitoring clarifications land cleanly — the S1/$0 cross-reference at L36 is exactly the right fix, and the "meaningfully reduce loss against this specific exploit" addition at L88 makes the modifier's trigger a property of the bug rather than the deployment, which was the important one. The two open items here are polish rather than blockers. Review checklist
|
Mintlify treats $...$ pairs as LaTeX math delimiters, so dollar-denominated amounts were rendering as italicized equations. Escape every $ in the page.
|
Claude finished @clemsos's task in 1m 36s —— View job Code Review — Bug Bounty Program rewrite (follow-up)Re-reviewed after the latest commit (
Fix in this commit
Still outstanding (minor, non-blocking nice-to-haves)These two items have persisted from the 15:19 review. Not blockers for merge. 1. Quick checklist separator inconsistency — security/bounties.mdx:76-77 The ×1.25 line was updated to 2. Permanent-freeze example doesn't state why the freeze is unrecoverable — security/bounties.mdx:127-129 The Style / terminology
SummaryLatest commit is a correctness fix for MDX rendering — clean and contained. No content regressions introduced. The page reads as a self-consistent researcher contract; the two outstanding items are polish-tier. Ready to merge. Review checklist
|
No description provided.