Skip to content

feat(contracts): add claim_refund for unsuccessful bidders in agent_bidding (#355) - #463

Open
prissca wants to merge 1 commit into
Epta-Node:mainfrom
prissca:feat/355-agent-bidding-claim-refund
Open

feat(contracts): add claim_refund for unsuccessful bidders in agent_bidding (#355)#463
prissca wants to merge 1 commit into
Epta-Node:mainfrom
prissca:feat/355-agent-bidding-claim-refund

Conversation

@prissca

@prissca prissca commented Aug 30, 2026

Copy link
Copy Markdown

Summary

Adds claim_refund(env, task_id, bidder), letting a bidder reclaim their own bond directly rather than depending on the creator ever finishing the flow. Today, bond refunds only happen as a side effect of award_contract (which loops over every bidder and marks their bond refunded) — if the creator never calls reveal_bids/award_contract (goes silent, nobody reveals, auction stalls), every bidder's bond is stuck with no way out.

Design

  • Callable once the bidding period has definitively closed (now >= auction.deadline) and before the new resolution deadline (auction.deadline + CLAIM_WINDOW_SECS, 7 days) elapses — the "finality marker" the acceptance criteria asks for.
  • Idempotency and "proof of loss" both fall out of the same check: a bid whose bond is already refunded — whether from a prior claim or from award_contract's automatic refund (which includes the winner) — cannot be claimed again. This means no separate "is caller the winner" check is needed: if the auction resolved normally, everyone (including the winner) already has refunded=true and claim_refund correctly rejects with AlreadyRefunded; if it never resolved, nobody has been marked refunded yet and any bidder can reclaim once the window opens.
  • Two new error variants, appended (never renumbering existing ones, per this file's own documented convention): AlreadyRefunded (18), ClaimWindowExpired (19).
  • New RefundClaimedEvent under (bidding, refnd_clm).

Does not touch award_contract's existing auto-refund-everyone behavior — this is an additive escape hatch for the abandoned-auction case, not a replacement for the normal path, so the existing award_contract_refunds_all_losing_bidders and award_contract_creates_escrow_and_refunds tests are untouched and still pass as-is.

"Escrow returns on dispute" (also named in the issue's proposed scope) is not addressed here — there is no dispute-resolution mechanism anywhere in this contract to hook into, and building one is a substantially larger feature than this issue's acceptance criteria call for. This PR delivers exactly the two acceptance criteria.

Acceptance Criteria

  • Each loser can claim exactly once
  • No claim after escrow resolution deadline

Test plan

contracts/agent_bidding/src/lib.rs: claiming before the bidding deadline fails; claiming with no bid fails; a stalled auction's bond is successfully recovered; claiming twice fails (idempotency); claiming after the window expires fails; claiming after a normal award_contract resolution fails with AlreadyRefunded rather than double-processing; exactly one event is emitted per successful claim.

Verification note

No local Rust toolchain is available in this environment (link.exe fails on proc-macro2's build script — the same limitation hit on all other Rust contract work this session, e.g. Stellar-Deejah/-LineProof#234 and this repo's #444). Verified by close manual review instead: traced every new branch against the existing test suite's conventions in this same file, and confirmed CLAIM_WINDOW_SECS/RefundClaimedEvent/the two new Error variants are each referenced exactly where expected with no leftover unused imports. Would appreciate CI/a reviewer confirming cargo test -p agent-bidding locally.

Closes #355

…idding (Epta-Node#355)

Adds claim_refund(env, task_id, bidder), letting a bidder reclaim their own
bond directly rather than depending on the creator ever finishing the
flow. Today, bond refunds only happen as a side effect of award_contract
(which loops over every bidder and marks their bond refunded) — if the
creator never calls reveal_bids/award_contract (goes silent, nobody
reveals, auction stalls), every bidder's bond is stuck with no way out.

Design:
- Callable once the bidding period has definitively closed
  (now >= auction.deadline) and before the new resolution deadline
  (auction.deadline + CLAIM_WINDOW_SECS, 7 days) elapses — the "finality
  marker" the acceptance criteria asks for.
- Idempotency and "proof of loss" both fall out of the same check: a bid
  whose bond is already `refunded` — whether from a prior claim() or from
  award_contract's automatic refund (which includes the winner) — cannot
  be claimed again. This means no separate "is caller the winner" check
  is needed: if the auction resolved normally, everyone (including the
  winner) already has refunded=true and claim_refund correctly rejects
  with AlreadyRefunded; if it never resolved, nobody has been marked
  refunded yet and any bidder can reclaim once the window opens.
- Two new error variants, appended (never renumbering existing ones, per
  this file's own documented convention): AlreadyRefunded (18),
  ClaimWindowExpired (19).
- New RefundClaimedEvent under (bidding, refnd_clm).

Does not touch award_contract's existing auto-refund-everyone behavior —
this is an additive escape hatch for the abandoned-auction case, not a
replacement for the normal path, so the existing
award_contract_refunds_all_losing_bidders and
award_contract_creates_escrow_and_refunds tests are untouched and still
pass as-is.

"Escrow returns on dispute" (also named in the issue's proposed scope) is
not addressed here — there is no dispute-resolution mechanism anywhere
in this contract to hook into, and building one is a substantially larger
feature than this issue's acceptance criteria call for. This PR delivers
exactly the two acceptance criteria: idempotent one-time claims, and a
resolution deadline after which claims stop.

Tests (contracts/agent_bidding/src/lib.rs): claiming before the bidding
deadline fails; claiming with no bid fails; a stalled auction's bond is
successfully recovered; claiming twice fails (idempotency); claiming
after the window expires fails; claiming after a *normal* award_contract
resolution fails with AlreadyRefunded rather than double-processing;
exactly one event is emitted per successful claim.

Verification: no local Rust toolchain available in this environment
(link.exe fails on proc-macro2's build script — the same limitation hit
on all other Rust contract work this session, e.g. Epta-Node#234 in
Stellar-Deejah/-LineProof and Epta-Node#444 in this repo for Epta-Node#358). Verified by
close manual review instead: traced every new branch against the
existing test suite's conventions in this same file, and confirmed
CLAIM_WINDOW_SECS/RefundClaimedEvent/the two new Error variants are each
referenced exactly where expected with no leftover unused imports.

Closes Epta-Node#355
@vercel

vercel Bot commented Aug 30, 2026

Copy link
Copy Markdown

@Obiajulu-gif is attempting to deploy a commit to the Jaja's projects Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a claim function for unsuccessful bidders in agent_bidding

2 participants