Bounty Terms
Reference for bounty configuration options
BountyTerms Structure
struct BountyTerms {
uint256 bountyPercentage; // 0-100
uint256 bountyCapUsd; // Max per whitehat in USD
bool retainable; // Keep from recovered funds?
IdentityRequirements identity; // KYC level required
string diligenceRequirements; // For Named identity
uint256 aggregateBountyCapUsd; // Total cap across all whitehats
}
Fields
bountyPercentage
Percentage of recovered funds the whitehat receives.
- Range: 0-100
- Typical: 10%
- Note: Actual bounty is
min(recovered x percentage, bountyCapUsd)
bountyCapUsd
Maximum bounty per whitehat in USD.
- Typical: $1M - $5M
- Note: Requires oracle conversion to token amounts
retainable
Whether whitehats keep bounty from recovered funds.
| Value | Meaning |
|---|---|
true | Whitehat keeps bounty, sends rest to recovery |
false | Whitehat sends all to recovery, protocol pays separately |
identity
Identity verification requirements.
enum IdentityRequirements {
Anonymous, // 0 - No verification
Pseudonymous, // 1 - Consistent pseudonym
Named // 2 - Legal name verification
}
diligenceRequirements
Additional requirements for Named identity. May specify KYC provider, documentation needed, etc.
aggregateBountyCapUsd
Total cap across all whitehats for a single exploit.
- Value 0: No aggregate cap
- Non-zero: Total payouts ≤ this value
- Note: Cannot use with
retainable = true
Bounty Calculation and Settlement
This is the canonical reference for how a bounty is calculated and paid. The how-to guides — Execute an Attack and Claim Bounties — link here rather than restating it.
The formula
Individual Bounty = min(RecoveredValue x bountyPercentage%, bountyCapUsd)
If aggregateBountyCapUsd > 0:
Total Payouts ≤ aggregateBountyCapUsd (shared proportionally across whitehats)
| Recovered | Percentage | Cap | Bounty |
|---|---|---|---|
| $500K | 10% | $5M | $50K |
| $10M | 10% | $5M | $1M |
| $100M | 10% | $5M | $5M (capped) |
Converting the USD cap to tokens
bountyCapUsd is denominated in USD; convert it to a token amount with the current price:
uint256 capUsd = terms.bountyCapUsd; // $5,000,000
uint256 ethPrice = 2000; // from an oracle
uint256 capInEth = capUsd * 1e18 / ethPrice; // 2,500 ETH
Settlement: retainable vs return-all
The retainable field (above) decides how recovered funds are split:
retainable = true— keep your bounty from the recovered funds and send the remainder to the recovery address.retainable = false— send all recovered funds to the recovery address; the protocol pays your bounty separately.
The code patterns for performing the transfers (including multiple token types) live in Execute an Attack.
Examples
Standard Terms
BountyTerms({
bountyPercentage: 10,
bountyCapUsd: 5_000_000,
retainable: true,
identity: IdentityRequirements.Anonymous,
diligenceRequirements: "",
aggregateBountyCapUsd: 0
})
High-Value Protocol
BountyTerms({
bountyPercentage: 10,
bountyCapUsd: 10_000_000,
retainable: false,
identity: IdentityRequirements.Named,
diligenceRequirements: "Complete KYC via Persona",
aggregateBountyCapUsd: 50_000_000
})
Validation Rules
bountyPercentagecannot exceed 100aggregateBountyCapUsdcannot be used withretainable = trueaggregateBountyCapUsdmust be ≥bountyCapUsdif non-zero