Escrow lifecycle
How a Jury Escrow moves from creation to settlement: the signature release, the deadline refund, and the dispute path with the jury's binding ruling.
Jury Escrow is a two-party USDC escrow: a depositor locks funds for a payee. Releasing the funds needs the depositor’s signature; if the parties disagree, either one can route the case to the jury. A flat 1% fee is taken only when funds are paid out.
State at a glance
An escrow has no on-chain status enum; its state is derived from four boolean flags (released, refunded, disputed, settled):
- Active: funds locked, nothing settled.
- Disputed: frozen, waiting on a jury ruling.
- Released / Refunded / Settled: finalized; no further action.
1. Creation
The depositor approves the factory for the USDC amount, then calls:
factory.createEscrow(payee, deadline, amount, title, description);
- Reverts on a zero amount, a zero or self payee, a past deadline, or a title over 200 / description over 1000 bytes.
- The factory
CREATE2-deploys a fresh escrow and pulls the USDC straight into it. - Emits
EscrowCreated(escrow, depositor, payee, amount, title, description).
The escrow now holds the funds and is Active. The 1% fee applies only on payout; nothing is taken at creation.
2. Happy path
Release, with the depositor’s signature
The depositor signs the hash from getReleaseSignableMessage() (it binds the chain, escrow, payee, and amount, so the signature is single-use). Then anyone can submit it:
escrow.release(signature);
Pays the payee amount − 1%; the 1% fee goes to the factory. Sets the escrow Released. Blocked once the escrow is disputed or finalized.
Reclaim, after the deadline
If the deadline passes without a release, the depositor can pull a full refund (no fee):
escrow.reclaim();
Sets the escrow Refunded.
3. Dispute path
Either the depositor or the payee can escalate:
escrow.raiseDispute();
- Pays the protocol’s
sortitionDisputeFeein USDC (approve the escrow for it first). - Freezes the escrow, so
releaseandreclaimnow revert, and opens a Sortition dispute with the escrow as the arbitrable. The escrow’s title and description become the dispute’s, for the jury to read. - Emits
DisputeRaised(by, disputeId); the escrow is now Disputed.
The jury then runs its full lifecycle. When it resolves, the protocol calls rule(disputeId, outcome) back on the escrow, which acts on the verdict:
| Jury outcome | Escrow action | Resulting state | Event |
|---|---|---|---|
| P1 | Pay the payee amount − 1% | Released | Released |
| P2 | Refund the depositor in full (no fee) | Refunded | Reclaimed |
| P3 | Take the 1% fee, split the remainder 50/50 | Settled | SplitSettled |
| P4 / tie | Reopen: unfreeze, no payout | Active again | DisputeReopened |
disputed clears and no funds move. The parties can then release, reclaim (after the deadline), or raise a fresh dispute.Events reference
EscrowCreated · Released · Reclaimed · DisputeRaised · SplitSettled · DisputeReopened.
IArbitrable.rule.