Early rate$2,400 of senior audit time for $500. Early members keep the rate as it climbs.$2,400 of senior audit time for $500See how →
F-2026-0025·signature-replay

Escrow meta-authorizations underbind their payload and never expire

Fixedescrowarbitrationdispute-resolution
TL;DR

Escrow meta-transaction digests omit part of the payload they authorise and never expire. A holder of an unused signature can attach arbitrary evidence or dispute reasons, and signatures stay valid indefinitely.

Severity
LOW
Impact
LOW
Likelihood
MEDIUM
Method
MManual review
CAT.
Complexity
MEDIUM
Exploitability
LOW
02Section · Description

Description

Escrow meta-transaction digests omit part of the payload they authorise and carry no freshness binding. raiseDisputeFor hashes ("RAISE_DISPUTE", address(this), episode, signatureNonce, chainid) without reason; markDeliveredFor omits evidenceHash. A holder of a valid unused signature can therefore attach arbitrary narrative or evidence and make it permanent for that episode.

Separately, every meta-action is a bearer digest valid until its first compatible execution — no validUntil, no per-action nonce, no signer cancellation. The sharpest is COMMENCE_MILESTONE, which binds only (address(this), milestoneIndex, chainid): a retained or leaked signature lets any caller start milestone i's delivery clock at a time of their choosing, after which the permissionless autoReleaseMilestone pays the seller the full milestone amount without the buyer ever greenlighting the work.

Payee and amount are fixed at creation, so this is stale first use rather than repeated drain.

03Section · Recommendation

Recommendation

Move every Escrow meta-action to EIP-712 typed data binding the exact payload hash, the action, the episode, a per-action nonce and validUntil, over a domain carrying chainId and verifyingContract. Give COMMENCE_MILESTONE a short expiry specifically, given its autoReleaseMilestone coupling.

04Section · Resolution

Resolution

Fixed. Every meta-authorization is now an EIP-712 typed struct over the clone's own domain, binding the full payload — including reasonHash, evidenceHash and milestoneIndex — plus a validUntil capped at 3 days.

05Section · Affected files

Affected files

  • Escrow.sol#L456-L481, #L484-L504, #L506-L525, #L530-L539, #L557-L566, #L621-L628, #L833-L842
Status
Fixed
F-2026-0025