Protocol / Listing lifecycle
Listing lifecycle
Every state, every transition, every timer.
Every listing is a small on-chain state machine. Transitions are permissioned and each escrow pays out or refunds exactly once. A listing always carries a kind, a platform and a title; the handle is optional — a service or a credit bundle may have none.
| State | Meaning | Who can act |
|---|---|---|
| Active | Listed, buyable | anyone buys or boosts / seller edits or delists |
| InEscrow | Buyer paid, awaiting the handover | seller delivers or cancels / buyer refunds after the delivery window |
| Delivered | Account handed over, in review | buyer confirms or disputes / seller claims after the review window, or cancels |
| Sold | Paid out in USDG | buyer may rate the seller once, with an optional written review |
| Delisted | Hidden by the seller | seller may relist |
Timers and caps
| Rule | Value | Protects |
|---|---|---|
| Delivery window (refund) | 3 days after payment | the buyer: refundPurchase() refunds them if the seller never delivers |
| Review window (auto-release) | 3 days after delivery | the seller: claimPayment() pays them if the buyer is silent |
| Dispute freeze | until the platform resolves | the buyer: a raised dispute blocks the seller's auto-claim |
| Fee ceiling | 10% hard cap in code | everyone: the owner can never set a fee above it |
Disputes
While a listing is Delivered, the buyer can call raiseDispute(id, reason)— wrong credentials, a recovered account, anything broken about the handover. This freezes the seller's auto-claim. The platform then calls resolveDispute(id, releaseToSeller): either the escrow is released to the seller, or the buyer is refunded and the listing returns to the market. The buyer can always end a dispute themselves by confirming receipt.