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.

ValueMeaning
trueWhitehat keeps bounty, sends rest to recovery
falseWhitehat 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)
RecoveredPercentageCapBounty
$500K10%$5M$50K
$10M10%$5M$1M
$100M10%$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

  • bountyPercentage cannot exceed 100
  • aggregateBountyCapUsd cannot be used with retainable = true
  • aggregateBountyCapUsd must be ≥ bountyCapUsd if non-zero