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-0032·missing-event

Accounting field names, event semantics and the specification's own invariant diverge

Fixedescrowarbitrationdispute-resolution
TL;DR

releasedAmount counts refunded amounts as released, a full buyer refund emits no milestone event, and the specification's conservation invariant omits abandoned amounts, so indexers and invariant tests built from the spec reconstruct the wrong state.

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

Description

Three accounting and event semantics diverge from what a consumer of the contract's state would reasonably infer, and from the specification.

  1. releasedAmount is gross, not seller-paid. _resolveDisputeFunds adds the full milestone amount to releasedAmount (Escrow.sol#L713) and then splits it, so a 100% buyer refund still increments a field named "released". getRemainingAmount stays correct; any consumer reading releasedAmount as seller revenue does not.
  2. A full refund emits no milestone event. emit MilestoneReleased(idx, toSeller) sits inside if (toSeller > 0) (#L721-L724), so a 10,000-bps buyer ruling settles the milestone with no MilestoneReleased at all and a naive indexer never sees the state change.
  3. The specification's conservation invariant omits abandonment. docs/PROTOCOL_SPEC.md §7.1 states token.balanceOf(escrow) >= totalAmount - releasedAmount, but the escrowed quantity is totalAmount - releasedAmount - abandonedAmount. After any abandonUncommencedMilestones the stated invariant is violated by correct code, so an invariant test written from the specification would either fail or be written to the wrong property.
03Section · Recommendation

Recommendation

Emit a milestone settlement event unconditionally, publish canonical liability and lifecycle semantics for consumers, and correct §7.1 to include abandonedAmount. Test indexer reconstruction across settlement, abandonment, milestones and repeated disputes.

04Section · Resolution

Resolution

Fixed. sellerPaidAmount and buyerPaidAmount were added and the held-principal invariant is documented alongside them.

Status
Fixed
F-2026-0032