-
Notifications
You must be signed in to change notification settings - Fork 134
Closed
Labels
Beta-CampaignCampaign: Beta-CampaignCampaign: Beta-Campaigngood first issueGood for newcomersGood for newcomerssoroban-contract
Description
Admin-controlled release and refund (Issue #3) work well for normal cases, but a depositor may disagree with the admin's decision before it is made. The dispute mechanism gives depositors a time-limited window to flag an escrow for review. Once disputed, funds are frozen until the admin explicitly resolves the case — preventing unilateral admin action during an open dispute.
Task
Building on the code from Issue #3, implement the following in contracts/payment_escrow/src/lib.rs:
-
raise_dispute— depositor-initiated function that:- Requires the caller's signature
- Validates the caller is the escrow's depositor (returns
Unauthorizedotherwise) - Rejects if status is not
Pending(returnsEscrowNotPending) - Rejects if the escrow's
dispute_window == 0(disputes disabled — returnsDisputeWindowClosed) - Rejects if the current ledger timestamp exceeds
created_at + dispute_window(window expired — returnsDisputeWindowClosed) - Updates status to
Disputedand setsdispute_raised_atto current timestamp - Saves the updated escrow
- Emits a
"disputed"event
-
resolve_dispute— admin-only function that:- Requires admin authorization
- Loads the escrow by ID
- Rejects if status is not
Disputed(returnsEscrowNotDisputed) - Accepts a
release_to_beneficiary: boolparameter:true→ transfers funds to beneficiary, sets status toReleasedfalse→ transfers funds to depositor, sets status toRefunded
- Sets
resolved_atto current timestamp - Saves the updated escrow
- Emits a
"resolved"event
Files to Modify
contracts/payment_escrow/src/lib.rs
Acceptance Criteria
-
raise_disputerejects callers who are not the depositor -
raise_disputerejects escrows not inPendingstatus -
raise_disputerejects whendispute_window == 0 -
raise_disputerejects when the dispute window has expired -
raise_disputecorrectly transitions status toDisputed -
raise_disputerecordsdispute_raised_at -
resolve_disputerejects non-admin callers -
resolve_disputerejects escrows not inDisputedstatus -
resolve_disputecorrectly routes funds based onrelease_to_beneficiaryflag -
resolve_disputecorrectly sets final status (ReleasedorRefunded) -
cargo clippy -p payment_escrow -- -D warningspasses
Technical Notes
- The dispute window check:
env.ledger().timestamp() > escrow.created_at + escrow.dispute_window - For
resolve_dispute, compute the recipient address before the token transfer, then use it in both the transfer call and the event EscrowStatus::Disputedis defined intypes.rs— thereleaseandrefundfunctions from Issue Hrushi backend nestjs setup #3 do NOT handleDisputedstatus, which is intentional;resolve_disputeis the only exit path for disputed escrows
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Beta-CampaignCampaign: Beta-CampaignCampaign: Beta-Campaigngood first issueGood for newcomersGood for newcomerssoroban-contract