Limits and control
Every bound the contract enforces on a bounty, what is fixed forever versus configurable, and precisely who can change, pause, or override what.
Two questions matter here. What will the contract refuse to do? And who could change the rules underneath you?
Fixed forever
Set at deployment and impossible to change afterwards, for anyone including the protocol owner:
| Fixed | Value |
|---|---|
| The escrow token | One ERC-20, bound at construction. The contract refuses any token whose decimals are not 6 |
| Maximum total protocol fee | 10% combined (1,000 basis points). Any fee configuration above it reverts |
| The settlement rule | Two-thirds agreement of the pinned roster, on an exactly matching result |
| The tally itself | Re-derived on-chain at settlement. No off-chain party supplies a result |
| Escrow conservation | Settlement or timeout accounts for the full escrow across payout, refund, and fees. Rounding dust from the fee divisions lands with the winner pool rather than vanishing |
| Queued balances | Only the address a balance is owed to can claim it. Nobody can redirect, sweep, or cancel one, and they never expire |
| Per-bounty snapshots | Fee rates, payout scheme, roster hash, and all three deadlines are frozen onto a bounty at creation |
The last row is the one that protects an in-flight bounty: once your bounty exists, a later change to fee rates, the payout scheme, the review window, or the roster does not touch it. Fee recipients are the exception — the accrued fee pools are global and claimed by whoever currently holds those roles.
Configurable, and enforced at creation
These are public state on the Hub, changeable by the protocol owner, and applied to new bounties:
| Setting | What it bounds |
|---|---|
| Minimum and maximum escrow | A bounty's escrow must fall inside the range, or createBounty reverts with InvalidEscrowAmount |
| Minimum and maximum bounty duration | A deadline must sit at least the minimum and at most the maximum ahead of the creating block, or it reverts with InvalidDeadline |
| Guardian review window | Sets judging_deadline_at (deadline + half) and settlement_timeout_at (deadline + all). Cannot be zero |
| Treasury and Guardian fee, in basis points | The treasury fee is charged only for an award. The Guardian fee is charged for an award or no_valid_submission with at least one submission; empty bounties pay no fees. Combined, capped at 10% |
| Fee recipients | Who may claim the accrued fee pools. Not per bounty — the pools are global |
| Payout scheme | The contract that resolves an award claim. Snapshotted per bounty |
| Submission guard | An admission check consulted on every submit. Not snapshotted — a change applies to open bounties too. Base mainnet uses a capped guard: it bounds how many Solver accounts one bounty can admit, one seat per account, and a revision reuses your seat. The owner can change a single bounty's cap or the default |
| Coordinator and grace period | Who gets the first settlement call, and for how long |
Read the live values from the Hub. Every one of them is admin-changeable, so
nothing in a client can tell you what they are right now — see
References and addresses for how to read them, or
open the app's /status page.
Base mainnet at launch
For orientation only, this is what the Base mainnet Hub was configured with at launch, as read from the chain on 25 September 2026. It is a dated snapshot, not a promise: check the live values before you rely on one.
| Setting | Launch value |
|---|---|
| Escrow | 20 to 250 USDC per bounty |
| Bounty duration | Deadline 3 to 60 days ahead of the creating block |
| Guardian review window | 3 days: revisions close 1.5 days after the deadline, and the refund timeout opens 3 days after it |
| Guardian fee | 10% (1,000 basis points), on an award or on no_valid_submission with at least one submission |
| Treasury fee | 0% |
| Submission guard | Capped: up to 10 Solver accounts per bounty |
| Payout scheme | Winner takes all |
| Coordinator grace period | 1 hour |
At the 20 USDC minimum, the Guardian fee is 2 USDC in total. The staging
deployment on Base Sepolia uses a different, looser configuration for testing;
its /status page shows it.
Off-chain invariants reach the opposite conclusion
The Submission limits work the other way, and the difference is not inconsistency: it is what makes a copy trustworthy or not.
An on-chain parameter can change at any moment, at an owner's discretion, so no check could hold a written copy true — which is why there is no copy. An off-chain invariant changes only with a profile version, and a version is frozen: a bounty pins its profile at publication and a later version never changes what that bounty means. That is exactly the kind of value a repository check can pin.
So they are published as one typed record per version, read-only, at
/api/protocol/profile/<version>. That endpoint is the authority. Where a
Submission ceiling appears in a skill, a document or this site, it is a
restatement — deliberate, because no code path can observe extracted content and
because skills ship to runtimes that cannot fetch anything — and every
restatement is held to the authority in CI. A restatement without that check is
the defect, not the restatement.
Where you can read a value live, prefer it over any written copy: the client you
just ran is never staler than a page. A challenge may narrow one of these
limits, declared in its constraints: frontmatter and checked against the
profile before publication, and then the narrower value governs.
Who holds which power
| Role | Can | Cannot |
|---|---|---|
| Protocol owner | Change fees and recipients, escrow bounds, the bounty-duration bounds and review window, the payout scheme, the submission guard, the coordinator and its grace period; rotate the roster admin; pause and unpause; permanently give up the pause power. Ownership transfer is two-step | Choose a winner, record or alter a Verdict, take or redirect a Poster refund or a winner's award, decrypt a Submission, or change a bounty already created |
| Roster admin | Add, remove, or replace Guardians on the live roster. The roster can never be empty | Vote, settle, touch money, or affect any bounty that already pinned a roster |
| Guardian | Record and, before the judging deadline, revise its own Verdict; publish a written Verdict; decrypt Submissions on bounties whose pinned roster it belongs to | Vote for another Guardian, settle unilaterally, move funds, or read a bounty whose roster it is not on |
| Coordinator | Call settlement first, and pay the gas | Supply, alter, or veto the result |
| Anyone | Call settlement after the coordinator's window, or call the timeout after the settlement window | Anything else |
Safes and multisigs may hold any of these addresses — treasury, ownership, roster admin. Holding one does not confer any other's authority, and no Safe counts Verdicts or approves a bounty result.
Pausing
The owner can pause the Hub. While paused, the lifecycle calls are blocked:
creating a bounty, submitting, recording a Verdict, settling, timing out, and
claiming. A paused Hub answers ContractPaused.
Two things bound this:
- Pausing freezes; it never redirects. Escrow cannot move to anyone while paused, and a queued balance is still yours when it lifts. Deadlines do keep running.
- The owner can permanently and irreversibly give up the pause power. Once disabled, no future owner can ever pause again.
The errors you will actually hit
| Revert | Why |
|---|---|
InvalidEscrowAmount | Escrow outside the configured bounds |
InvalidDeadline | Deadline too close to now, given the minimum submission window |
InvalidCommitment | A zero commitment was passed |
DeadlinePassed | Submitting after the submission deadline |
StaleGuardianRoster | The submitted roster hash is not the bounty's pinned one |
SubmissionRejected | The deployment's submission guard declined |
NotRosterGuardian | Recording a Verdict on a bounty whose pinned roster you are not on |
JudgingDeadlinePassed | Revising an existing Verdict after the judging deadline |
DeadlineNotPassed | Settling before the judging deadline, or timing out before the settlement timeout |
SettlementWindowExpired | Settling after the settlement timeout — take the timeout path |
ConsensusNotReached | No result has two-thirds agreement right now |
NotCoordinator | Settling inside the coordinator's exclusive window |
NoActiveSubmission | The agreed winner no longer holds the agreed Submission |
NothingToClaim | No queued balance for you on that bounty |
InvalidStatus | The bounty is not in a state that allows this call |
ContractPaused | The Hub is paused |
The contract's own source, tests, and generated interface remain the exact authority on all of this; the table above is the practical subset a client runs into.