Contract overview

The BountyMesh contract is a Sails program on Vara mainnet. Nine service methods drive the bounty lifecycle (5 happy-path + 4 transition), nine events project state changes for off-chain indexers, and 21 typed error variants cover every rejection path.

Program ID:  0xfa09abea4ac2de874bc115cfcfd0992e07636ee9f74e62a21b3750fd6f218886
Deploy block: 33364616
Constructor:  New(min_reward: u128, auto_settle_blocks: u32)
Mainnet args: (500_000_000_000, 50_400)  // 0.5 VARA floor, ~3.5d auto-settle window

Verify on Subscan.

Service surface

service BountyService {
  // Happy path
  Post     (title, description, acceptance, reward, deadline?, track) -> Result<u64, Error>
  Claim    (id)                                                       -> Result<(), Error>
  Submit   (id, result_payload, result_hash)                          -> Result<(), Error>
  Accept   (id)                                                       -> Result<(), Error>
  Withdraw (id)                                                       -> Result<(), Error>

  // v2 transitions — terminal states
  Cancel   (id)                                                       -> Result<(), Error>  // poster, Open
  Reject   (id, reason?)                                              -> Result<(), Error>  // poster, Submitted
  Timeout  (id)                                                       -> Result<(), Error>  // permissionless, after deadline
  Revoke   (id)                                                       -> Result<(), Error>  // owner emergency

  events {
    BountyPosted    { id, poster, reward, track, posted_at, title, description, acceptance, deadline }
    BountyClaimed   { id, worker, claimed_at }
    BountySubmitted { id, worker, result_hash, submitted_at }
    BountyAccepted  { id, poster, worker, reward, settled_at }
    BountyWithdrawn { id, worker, amount, withdrawn_at }
    BountyCancelled { id, by, refunded, cancelled_at }
    BountyRejected  { id, by, worker, reason, rejected_at }
    BountyTimedOut  { id, last_state, called_by, refunded_to, timed_out_at }
    BountyRevoked   { id, by, refunded_to, revoked_at }
  }
}

State model

The on-chain Bounty struct lives in BTreeMap<BountyId, Bounty>. Each entry carries:

idu64

Sequential bounty ID. Counter increments by checked_add(1); exhaustion returns Error::IdSpaceExhausted (unreachable at any realistic scale).

posterActorId

msg::source() at the time of Post. Immutable.

workerOption<ActorId>

Set at Claim. Immutable once set.

titleString (≤ 200 chars)

Locked at Post. Emitted in BountyPosted event.

descriptionString (≤ 2000 chars)

Locked at Post.

acceptanceString (≤ 1000 chars)

Locked at Post.

rewardu128

Locked at Post. Stays in program escrow until Withdraw.

deadlineOption<u32>

Optional block height for advisory auto-settle window. Currently informational.

trackTrackEnum

Services | Economy | Social | Open. Filtered by worker daemons.

statusBountyStatus

Open | Claimed | Submitted | Accepted | Rejected | Cancelled | TimedOut | Revoked. All 8 variants reachable in v2.

result_payloadOption<String>

Set at Submit. The canonical-JSON envelope.

result_hashOption<H256>

Set at Submit. The sha256 of canonical_json(envelope).

withdrawnbool

Flipped to true at Withdraw. One-way; no reset path.

Four secondary index maps speed reads: bounties_by_status, bounties_by_poster, bounties_by_worker, bounties_by_track. They are NOT load-bearing for correctness — the contract enforces invariants on the primary map; the indexes back the indexer's projection queries.

Lifecycle

                 Post                Claim              Submit             Accept            Withdraw
  [void]  ──────────────▶ Open ─────────▶ Claimed ──────────▶ Submitted ──────────▶ Accepted ───────────▶ Withdrawn
                          │              │                    │
                          │              │                    └──── Reject ─▶ Rejected
                          │              └──── Timeout ─▶ TimedOut
                          ├──── Cancel ─▶ Cancelled
                          └──── Timeout ─▶ TimedOut

  (any non-Revoked state) ─── Revoke (owner) ─▶ Revoked

See Bounty lifecycle for transition details + error coverage per state.

Method index

Cross-references

  • Events — all 5 emitted variants with full payload schemas
  • Errors — 17 typed variants + which methods can return each
  • Anti-cheat — self-loop rejection + refund correctness
  • Reference IDL — full machine-readable IDL exported from the build artifact

Source

programs/bountymesh/app/src/ on GitHub. The interesting files:

  • service.rs — the 5 service methods, ~450 LoC, every guard documented inline
  • state.rs — the Bounty struct + BountyMeshState (BTreeMap + indexes) + length constants
  • events.rs — the 5-variant Event enum
  • errors.rs — the 17-variant Error enum
  • lib.rs — program constructor + service wiring