In the current design the verifier holds tokens off-chain and calls complete_bounty to push
them to the assignee via token.transfer. The contract itself never holds a token balance.
The attack surface is limited to:
- Authentication bypass — every state-changing function calls
require_auth()on the relevant actor (creator, contributor, or verifier). - Double-assignment —
claim_bountypanics ifassigneeis alreadySome. - Monotonic reputation — reputation only ever increases; no underflow path exists.
When escrow is introduced the contract will hold tokens on behalf of bounty creators
(create_bounty transfers reward tokens into the contract; complete_bounty and
cancel_bounty transfer them out). This changes the threat surface significantly.
The contract's token balance for any given token must always equal the sum of
reward_amountacross all bounties inopenorin_progressstatus that use that token.
Maintaining this invariant is the primary correctness goal for all escrow-related code paths. Any deviation — even transient — represents a fund safety bug.
Description: A bug prevents a bounty from ever reaching completed or cancelled, locking
the escrowed tokens permanently.
Example scenarios:
cancel_bountypanics unconditionally due to a logic error.- Status index corruption leaves a bounty in an unresolvable state.
- A missing code path for a status transition leaves a bounty stuck.
Mitigations:
- Ensure
cancel_bountyis callable by the creator for any bounty inopenorin_progressstatus — it must always provide an exit. - Consider a verifier-only emergency cancel path as a backstop.
- Write invariant-checking tests that verify the contract balance equals the sum of open bounty rewards after every state transition.
Description: An attacker triggers multiple payouts for a single bounty, draining more tokens
than the bounty's reward_amount.
Example scenarios:
complete_bountyis called twice before the status is persisted ascompleted, paying the reward twice (a classic check-effects-interactions violation).- Reentrancy via a malicious token contract that calls back into
complete_bountyduringtoken.transfer.
Mitigations:
- Follow checks-effects-interactions strictly: update the bounty status to
completedand persist it before callingtoken.transfer. - Validate that
bounty.status == STATUS_IN_PROGRESSat the top ofcomplete_bountyand panic otherwise — this prevents double-completion even without reentrancy guards. - Note: Soroban's single-contract-at-a-time execution model eliminates classic reentrancy, but the ordering discipline should still be enforced for clarity and defence-in-depth.
Description: A malicious actor creates many bounties (locking the minimum viable reward in each) and immediately cancels them, burning transaction fees and polluting the status index.
Example scenarios:
- Rapid create → cancel cycles pad the
cancelledindex, increasing read costs forget_bounties_by_status("cancelled"). - Large numbers of
openbounties with tiny rewards deter legitimate contributors.
Mitigations:
- Enforce a minimum
reward_amountincreate_bountyto raise the economic cost of griefing. - Consider a creation fee (paid to the contract or burned) that is separate from the bounty reward, making spam attacks self-limiting.
- The status index is unbounded today; if griefing is a concern, cap index length or paginate reads.
| Function | Risk | Key invariant to enforce |
|---|---|---|
create_bounty |
Token transfer in; under-transfer | contract_balance += reward_amount after the call |
complete_bounty |
Token transfer out; double-payment | Status set to completed before token.transfer |
cancel_bounty |
Token transfer out; stuck-fund if blocked | Always reachable by creator; status set before transfer |
- Fuzz
reward_amountedge cases (0,i128::MAX, negative). - Add an integration test that asserts
contract_balance == sum(open + in_progress rewards)after each transition. - Confirm
complete_bountypanics when called on an already-completed bounty. - Review token contract for any re-entrant callbacks into this contract.
- Have at least one contributor who was not the author review the token transfer ordering.