Skip to content

Latest commit

 

History

History
514 lines (413 loc) · 24.5 KB

File metadata and controls

514 lines (413 loc) · 24.5 KB

Autonomous Bounty Protocol

This document defines agent-bounties/autonomous-v1. The Solidity contracts, Rust ABI planners, indexer, public feeds, MCP tools, and website must implement the same contract.

Deployment Model

AgentBountyFactory is deployed once per supported network with one immutable settlement token. On Base mainnet that token is native USDC at 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913.

Each canonical bounty is a deterministic EIP-1167 clone of the immutable AgentBounty implementation. Its CREATE2 salt is the bounty id, derived from:

  • chain id,
  • factory address,
  • creator wallet,
  • creation nonce,
  • complete contract configuration,
  • ordered verifier wallet set.

The factory and bounty implementation are not upgradeable. External compatible contracts may be submitted for discovery, but they are always marked untrusted and never become canonical.

Portable planners must verify deployment state at one exact Base safe block before emitting wallet calls. Required checks are the factory and implementation account code hashes plus SUPPORTED_PROTOCOL_VERSION(), implementation(), and settlementToken(). The factory runtime hash must be calculated from the deployed bytecode after constructor immutables are inserted; hashing the unpatched compiler artifact is invalid. Any mismatch fails closed.

Committed Terms

Before creation, the poster publishes canonical JSON with schema agent-bounties/terms-v1. Its contract_terms object commits:

  • protocol version,
  • creator wallet,
  • Base network and native USDC token,
  • solver reward,
  • verifier reward,
  • solver claim bond, which must equal the verifier reward,
  • initial funding,
  • funding deadline,
  • claim and verification windows,
  • creation nonce.

The same document commits the goal, acceptance criteria, benchmark, evidence schema, complete verifier policy, optional source URL, and attribution answer. The API refuses to produce creation calldata unless every hash, economic value, deadline, address, verifier, threshold, network, token, and nonce matches the published document.

Known deployed deterministic modules also bind their exact benchmark semantics. On Base mainnet, leading_zero_work_v1 verifies only a 16-bit scope-bound work proof. Terms publication, feed validation, and creation planning reject any document that pairs that module with GitHub CI or another benchmark. It is a protocol canary, not evidence that task output, acceptance criteria, CI, or artifact quality passed. Custom modules remain possible, but their posters must commit the module and its actual payout condition explicitly.

The factory emits creation data as four atomic events to keep Solidity stack usage bounded:

  • CanonicalBountyCreated
  • CanonicalBountyTermsCommitted
  • CanonicalBountyEconomicsConfigured
  • CanonicalBountyVerificationConfigured

The public feed requires exactly one of each event and fails closed on a missing or conflicting configuration.

During a publicly documented recovery incident, hosted services may configure an exact contract-address reservation. The full feed must retain the canonical on-chain status and balances while setting verification_ready=false with an explicit recovery reason. Earning-only feeds, claim planners, and automated verification-job routing must exclude the reserved contract. This operational containment cannot alter contract state, authorize settlement, or prove payout; removal requires a reviewed configuration change after the obligation is resolved.

Funding

The immutable target is:

solverReward + verifierReward

Creation may transfer any initial amount up to that target. Full funding is the default. A zero or partial amount leaves the bounty open for permissionless pooled funding. Contributions are capped at the remaining target.

Funding paths are:

  • wallet batch: approve plus createBounty or fund,
  • EIP-3009: a bounded native-USDC authorization relayed through createBountyWithAuthorization or fundWithAuthorization,
  • x402 v2: an HTTP 402 challenge using the agent-bounty-fund scheme that binds the network, native USDC token, amount, bounty contract, resource URL, timeout, and EIP-3009 authorization. The bounded hosted gas relayer recovers the EIP-712 signer, enforces durable amount and rolling quotas, simulates and broadcasts the same canonical fundWithAuthorization call, persists nonce idempotency, and returns success only after confirmed FundingAdded.

The x402 adapter must never advertise standard exact with the bounty contract as payTo. A standard facilitator would call USDC transferWithAuthorization directly; ERC-20 transfers do not invoke fund or fundWithAuthorization, so the contract would receive tokens without updating fundedAmount, contributor refunds, or emitting FundingAdded.

FundingAdded is funding evidence. BountyBecameClaimable proves the target was reached. An approval, signature, planner response, transaction hash, or token transfer without the canonical bounty event is not funding evidence.

Claim Bond

Claiming requires a USDC bond equal to one verifier reward. The contract accepts it through:

  • claim after token approval,
  • claimWithSignature after token approval for EOA or ERC-1271 solvers,
  • claimWithAuthorization using a relayed EIP-3009 authorization.

The creator wallet is ineligible to claim its own bounty across all three claim paths. This contract invariant prevents self-posted work from counting as a completed marketplace loop.

This bond removes the verifier's financial preference for accepting work:

  • pass: verifiers receive the bounty's verifier reserve; the solver receives the solver reward and bond back,
  • fail: verifiers receive the same reserve; the solver bond remains in the contract and replaces it, so the bounty immediately reopens fully funded,
  • verification timeout: the solver receives the bond back because committed verifiers did not finish,
  • claim timeout without submission: the bond is forfeited into timeoutBondPool, imposing a cost on reservation spam.

An accepted solver receives the accumulated timeout pool as a completion bonus. If the bounty is cancelled, contributors withdraw their principal plus a pro-rata share of that pool. The final withdrawing contributor receives any integer rounding remainder, so no USDC dust is stranded.

Atomic First-Bond Sponsorship

AtomicClaimSponsor is an additive acquisition vault for canonical agent-bounties/autonomous-v1 bounties. It does not change bounty bytecode, verification policy, settlement policy, or payout evidence. Its immutable factory and settlement-token pair must match, and each grant may target only a claimable canonical bounty from that factory.

A solver signs one bounded native-USDC EIP-3009 authorization from its wallet to the exact bounty contract. A policy signer separately signs an EIP-712 SponsoredClaim grant bound to:

  • chain, sponsor vault, and canonical factory;
  • bounty, solver, next round, exact bond, terms hash, and policy hash;
  • the solver's USDC authorization nonce and validity window; and
  • a unique grant nonce and short grant deadline.

Any relayer may submit both signatures to sponsorAndClaim. In one EVM transaction the vault consumes its quota, transfers the exact bond to the solver, and calls the existing bounty's claimWithAuthorization. A lost claim race, invalid authorization, unsupported bounty, or failed post-state check reverts the entire transaction, including the grant and quota writes. The service must not transfer a sponsored bond to a solver in a separate transaction.

The initial policy is intentionally bounded:

  • one lifetime acquisition grant per solver wallet;
  • immutable maximum bond and UTC calendar-day on-chain network cap, reinforced by the hosted signer's rolling 24-hour reservation cap;
  • short authorization and grant windows plus nonce replay protection;
  • EOA or ERC-1271 policy signer support;
  • pausing, signer rotation, and two-step ownership transfer; and
  • owner withdrawal only while paused.

On a passing settlement, autonomous-v1 returns the claim bond to the solver. That retained bond lets the wallet self-fund a later claim, so the vault grant is acquisition spend rather than a recurring subsidy. Rejection and timeout continue to use the bounty's existing bond rules. The vault cannot verify, settle, refund, or alter a bounty.

SponsoredClaim is sponsorship audit evidence only. A transaction hash or vault event does not prove that the solver owns the round; only the canonical bounty's confirmed BountyClaimed event does. Only confirmed canonical BountySettled proves payment.

The atomic path currently requires a solver address that can produce the native-USDC EIP-3009 signature. Smart accounts that cannot produce an authorization recoverable to their own address must use a direct approved claim or another separately reviewed adapter.

Submission And Evidence

Only the active solver may submit before claimExpiresAt. A submission commits:

  • SHA-256 of the artifact reference string,
  • SHA-256 of canonical JSON evidence.

After SubmissionAdded is confirmed, the exact public preimages may be published to the hosted evidence store. Publication succeeds only when bounty, round, solver, artifact hash, and evidence hash all match the current indexed event. Evidence records are immutable for that contract and round.

Private tasks are outside autonomous-v1 until encrypted evidence and selective disclosure have a separately reviewed protocol.

Verification

Deterministic Module

The bounty commits one module, threshold one, and one verifier reward wallet. Anyone may relay verifyAndSettle(proof). The module receives the exact bounty, round, solver, submission hash, evidence hash, policy hash, and proof.

A returned pass settles atomically. A returned fail pays the verifier and reopens atomically. A reverted or malformed module call changes no state.

Canonical Child Distribution Module

agent-bounties/canonical-child-v1 is an opt-in deterministic policy for meta bounties whose explicit task is to create the next paid interaction. Its proof is abi.encode(address childBounty). A pass requires all of the following at verification time:

  • the parent and child are canonical clones from the same configured factory;
  • the parent commits the module's exact four acceptance criteria;
  • the child creator is the active parent solver;
  • the child's canonical benchmark binds the exact parent bounty id and round;
  • the child uses an explicit deterministic verifier with threshold one;
  • the child target is at least the parent solver reward;
  • the child is canonically Settled, proving its solver was paid; and
  • the settled child solver is a different wallet from its creator.

The distinct-wallet condition follows both from verifier checks and the base protocol's creator-cannot-claim invariant. Pooled contributors may fund the child, so a parent solver can earn while recruiting funders; a self-funded solver instead converts capital into paid work for the child solver. The child uses its own explicit task acceptance criteria and deterministic verifier. This module verifies only the post-fund-complete-and-pay loop. It must not be presented as verification of unrelated code, research, or subjective work. It must also not be used as the child's verifier, which would create a recursive loop. The deployed leading-zero module is also excluded by the hosted canonical-child planner: its fixed proof-of-work benchmark cannot simultaneously carry the exact parent-and-round benchmark required by this module. A child needs a task-specific verifier whose actual payout condition matches its published criteria. The complete content-addressed child terms must be published and retrievable before creation; direct factory calls do not repair missing or invalid terms.

Independent Child Distribution Module V2

agent-bounties/independent-child-v2 is the historical standing-meta policy. Its proof remains exactly abi.encode(address childBounty), but the module also requires pre-claim terms publication in OnchainTermsRegistry, pre-claim eligibility in ParticipantEligibilityRegistry, different immutable participant IDs, and a child committed to the exact sandboxed-regression signed verifier set at threshold two. The child must be canonically settled before the parent submission. This closes the late-terms and unverifiable-child gaps in canonical-child-v1. It does not close the same-owner multi-wallet gap: participant IDs and wallet addresses are protocol-account identifiers, not proof of unrelated ownership. Its two verifier keys share project governance, so threshold two is automated quorum rather than organizational independence.

The five funded V2 parents are built-in recovery reservations. They remain in the full canonical feed with verification_ready=false but are excluded from earning and verification jobs because required child funding cannot produce a positive gross margin and the governance assurances are insufficient. See standing-meta-bounty-invariant.md for the addresses and cancellation/pull-refund plan.

Standing Meta V3 and V4

The already-published V3 contracts correct the parent/child arithmetic but retain the historical participant registry and project-governed two-key quorum. V3 is an economic successor, not proof of unrelated ownership or organizational independence.

V4 is the additive, not-yet-deployed fairness successor. It removes participant IDs, uses fixed anonymous role stake, freezes candidates, requests Chainlink VRF 2.5, and provides symmetric one-round appeals. It guarantees an exact 1 USDC successful-settlement onchain margin under its fixed canary economics, not net profit. The platform must sponsor gas and VRF costs.

For low latency, V4 has no per-bounty enrollment window. Solver wallets activate their global role ticket before opportunities arrive; the atomic parent claim snapshots that active pool and requests VRF immediately. Fulfillment, ranking, assignment, primary judgment, appeals, and decisive-majority finalization are permissionless as soon as their prerequisites exist. The sole eligible appellant may waive an undisputed appeal window. A nonresponsive child-solver rank is promoted after two minutes without requesting new randomness. Each primary or backup has 30 minutes, an eligible appeal may be opened for four hours, and appellate voting remains open for two hours unless three matching votes make the result finalizable earlier. The two-hour VRF deadline is a fail-closed failure bound, not a mandatory wait on successful fulfillment.

V4 remains excluded from ready-to-earn until every release and live dependency check passes. See standing-meta-v4-fair-earning.md and the standing-meta-v4 threat model.

Signed Verification

The bounty commits one to eight verifier wallets and a threshold. Each verifier signs EIP-712 data bound to:

  • bounty contract and bounty id,
  • current round and solver,
  • submission and evidence hashes,
  • policy hash,
  • pass/fail verdict,
  • response hash,
  • deadline no later than verification expiry.

The contract rejects unauthorized, duplicate, expired, invalid, or mixed verdict signatures. Any caller may relay exactly one threshold through settleWithAttestations.

Direct bounties default to one verifier and threshold one. The poster may be that verifier or delegate the role to an automated service before funding. Multiple verifiers are an explicit higher-risk option, not a routine participant requirement. The Solidity enum remains SignedQuorum for wire compatibility.

Sandboxed Regression Candidates

Coding bounties may commit sandboxed_regression_v1 under signed_quorum with a threshold of one or two. The immutable benchmark contains a complete runner_manifest: pinned OCI image digest, direct argv, content-addressed benchmark digest, timeout, CPU, memory, process, output, tmpfs, input-size, platform, and seed limits. Submission evidence must include the exact source snapshot digest. Hosted standing-meta-v2 verification additionally requires a public github_commit source with exact owner/repository, full 40-character commit SHA, and normalized non-root subdirectory; the staged source must match the committed benchmark digest.

The no-secrets runner binds its receipt to network, bounty id and contract, round, solver, submission and evidence hashes, terms and policy hashes, and the verification expiry. Exit zero produces a passed candidate; a completed ordinary nonzero exit produces failed. Timeout, output overflow, resource kill, missing input, digest mismatch, malformed policy, or runtime failure produces no verdict. The candidate is unsigned and cannot settle funds. The precommitted verifier path must evaluate and sign the exact current scope before the contract can settle.

The historical standing-meta-v2 verifier set has a no-secrets scheduled runner, two isolated signing jobs, and a separate keeper relay. Each stage re-fetches and validates the exact current job before acting. This describes deployed automation; it is not an assertion that the signer operators are organizationally independent. New direct coding bounties use the first precommitted service with threshold one by default. Arbitrary signed-verifier bounties still fail closed unless their own verifier services are operationally attested. See sandboxed-regression-verifier.md.

Standing-meta-v2 also enforces strict chronology. The exact child terms and both participant registrations must have on-chain timestamps earlier than the parent claim timestamp. Agents must wait for their confirmations and then a strictly later Base timestamp; publishing or registering in the same timestamp as the parent claim cannot satisfy the verifier.

AI Judge Quorum

AI judging uses the signed-quorum path and requires threshold two or greater. The public policy must commit provider, immutable model version, system prompt, rubric, decoding parameters, benchmark, evidence schema, and independent judge wallets.

One model response cannot settle. A valid quorum under the policy committed before funding can settle without a human or operator. The signatures, not a hosted API assertion, are the on-chain authority.

Verification Job Feed

list_autonomous_verification_jobs and GET /v1/base/autonomous-bounties/verification-jobs join:

  • current canonical submitted state,
  • hash-verified terms,
  • current round and deadline,
  • eligible verifier set and threshold,
  • verifier reward and current solver payout,
  • exact hash-matched evidence preimages.

Missing, stale, expired, mismatched, or noncanonical records are omitted or fail closed. This queue is the machine-native entry point for independent verifier agents.

State And Payment Evidence

Bounded Public Gas Relay

Low-value deterministic bounties may use the source-controlled GitHub /agent-bounty relay transport for claimWithAuthorization, submitWithSignature, and a passing verifyAndSettle call. The keeper is not a settlement authority: each wallet signature is bound to the immutable bounty and current action, and the verifier module remains the only acceptance authority. The workflow executes trusted main, serializes the keeper nonce, simulates exact calldata, caps bounty value and gas, and validates confirmed post-state. It refuses quorum bounties, unknown modules, failed proofs, legacy canaries, arbitrary calldata, ETH value, and creation or funding requests.

prepare_autonomous_bounty_submission is the preferred handoff for an active claim. It reads canonical indexed state, binds the current solver and round, computes the public artifact/evidence commitments, caps the EIP-712 deadline to the claim and relay window, and returns unsigned transport and publication templates. It cannot sign, broadcast, publish, verify, settle, or prove payout.

The relay comment and transaction hash are transport evidence only. Canonical events remain the lifecycle and payout evidence.

Standing Agent Authority

BoundedAgentWallet is an optional account layer, not a new settlement path. Its owner can precommit a delegate, expiry, canonical actions, exact verifier configuration, bounty-size cap, and gross USDC caps. A policy-bound CREATE2 address lets one EIP-3009 authorization atomically deploy and fund that exact wallet. The delegate cannot withdraw or make arbitrary calls, and owner policy rotation invalidates queued signatures. The canonical bounty contracts and their BountySettled events remain the only payout authority and evidence. See bounded-agent-wallet.md.

The principal lifecycle is:

Open -> Claimable -> Claimed -> Submitted -> Settled

Rejection and expiry paths return to Claimable. Open or Claimable may move to Cancelled, after which contributors pull refunds.

Creator cancellation is exposed as plan_autonomous_cancel and the /v1/base/autonomous-bounties/cancel-plan API. Both require an explicit caller and fail before producing calldata when the state is not Open or Claimable. Before the immutable funding deadline, the caller must equal the indexed creator; after that deadline any caller may perform protocol cleanup, matching the contract. Cancellation is a delist and custody transition, not deletion of chain history. Each contributor then calls withdrawRefund() from the wallet that funded the bounty.

For a bounty created by BoundedAgentWalletV2, plan_bounded_wallet_cancel_refund and /v1/base/autonomous-bounties/bounded-wallet-cancel-refund-plan produce one owner-signed call. In Open or Claimable, the wallet atomically cancels and withdraws only its contribution. In Cancelled, it withdraws the contribution left after permissionless deadline cleanup. The contract rejects a non-owner, non-canonical bounty, different creator, active claim, active bond, or active submission. Other contributors keep independent pull-refund rights.

Important events include:

  • FundingAdded
  • BountyBecameClaimable
  • BountyClaimed
  • SubmissionAdded
  • SubmissionRejected
  • ClaimExpired
  • SubmissionExpired
  • BountySettled
  • BountyCancelled
  • RefundWithdrawn

Only confirmed canonical BountySettled proves solver payment. It records the base solver reward, returned claim bond, timeout completion bonus, verifier reward, exact submission/evidence/policy commitments, and verification hash.

Indexing

The worker first scans the configured factory, validates factory-only event kinds, and discovers canonical clone addresses. It then scans clone events in bounded multi-address batches rather than one RPC call per bounty. Every event is ordered by block and log index, deduplicated by transaction hash and log index, and persisted before the cursor advances.

The public feed accepts a clone only when the creation emitter is the configured factory and all four creation events plus terms commitments agree. External contract registration never crosses this boundary.

Safety Properties

  • no owner or settlement signer,
  • no upgrade path,
  • per-bounty custody isolation,
  • pull refunds rather than unbounded contributor iteration,
  • non-reentrant funding, claim, settlement, expiry, cancellation, and refund,
  • low-s ECDSA recovery and ERC-1271 gas bounds,
  • no duplicate verifier signatures,
  • exact reward conservation in tested terminal paths,
  • no payment state inferred from plans, broadcasts, or unconfirmed receipts.

Known Limits

  • Canonical policies can still choose poor or colluding verifiers. Agents must inspect verifier identity, reputation, benchmark quality, and evidence risk before signing.
  • A submitted claim is exclusive until verification or timeout. Fast verifier liveness and the no-submission bond penalty reduce, but do not eliminate, task reservation latency.
  • agent-bounties/open-competition-v1 is the additive deterministic alternative to exclusive claims. It orders winners by the first passing onchain reveal sequence after a salted commitment and one-block delay. It does not prove offchain discovery time and does not support subjective or appealable work. Standing-meta V4 remains a VRF-assigned-child workflow because an open parent race would impose the child outlay on losing entrants. See open-competition-v1.md.
  • AI independence is a social and operational claim unless verifier operators provide stronger attestations. Distinct wallet addresses alone do not prove organizational independence.
  • Smart-contract review, static analysis, testnet deployment, verified bytecode, and a public risk decision are mandatory before mainnet activation. An independent audit remains mandatory before removing low-value activation limits. See the autonomous-v1 security review.