Files
dex/pkg
zeekayandHanzo Dev 9061f81167 dexprotocol: a reclaimed export cannot become writable
The D->C leg is the sharpest monetary edge in the system. D debits the
owner and writes an object for C to consume; if the write is lost, the
value has left D and never arrives. Refunding on a timer is the obvious
repair and is a double-spend waiting to happen — the moment a refund and
a late delivery can both take effect, the value exists twice.

The property that must hold: after a reclaim, no copy of the original
object, however delayed or retried, can ever become importable on C.

It is structural rather than argued, and the mechanism is who can obtain
the bytes:

  Available --Export--> Pending --Deliver--> Delivered --retry--> C
                           |
                           +---Reclaim---> Available

PendingExport exposes no Claim. There is no accessor, so the object to
write cannot be obtained while a reclaim is still possible. Only Deliver
produces one, and Deliver MOVES the record out of the pending domain, so
a record is either reclaimable or writable and never both. The write is
therefore only ever attempted from a committed Delivered state — the same
commit-then-apply discipline the import leg already uses.

A timeout is not the recovery mechanism. Delivery is retryable from
durable state for as long as it takes, and Redeliver returns a
byte-identical object, which is what makes C's exactly-once import treat
a duplicate arrival as the replay it is rather than a second claim.

Pending value still counts as D's in the rail equation:
imported - delivered == owned + earmarked. It has left the owner's
available balance but has not crossed, and a reclaim brings it back;
counting it as gone would make every open export read as a shortfall.

Six attacks, all refused: deliver after reclaim, redeliver after reclaim,
re-export under a reclaimed id, double reclaim, reclaim after deliver,
and the full two-chain reclaim-plus-late-delivery. Plus 500 randomly
sequenced steps asserting after each that no id is both reclaimable and
writable. 67 tests; the attack run closed at 10000 in - 660 delivered =
9323 owned + 17 earmarked.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-07 16:16:55 -07:00
..