Files
dex/pkg
zeekayandHanzo Dev c935e4d228 dexprotocol: the cross-chain exchange vocabulary, with the bug class unwritable
The C transaction contains an Order. D matches it and certifies an Execution —
price and quantity guaranteed and reserved. The C block carries that Execution.
EVM execution verifies it and returns the resulting BalanceDelta. When the child
of the Execution's C parent is accepted, D settles it into a Trade if that child
used it, or Releases the reservation if it did not.

This is the consensus-side half: the certified object, its canonical encoding
and domain-separated commitment, and the lifecycle.

WHY IT IS SHAPED THIS WAY

C never queries D's live state during EVM execution — that would fork C on the
first swap, since validators sit at different D heights. Instead D's statement
rides in the block and C verifies it. On replay D can be dead, the GPU gone, D a
billion blocks ahead; C has parent state, transactions, the statement, and the
certificate. That is the entire input set.

Move-typed storage, not a status field. ReservedExecution, Trade and Released
are distinct types under distinct key prefixes, and a transition MOVES the
object. Settle(Trade) and Release(Trade) do not compile — there is no reserved
execution left to hand them. This is aimed squarely at the live defect where the
intent record is written back only inside the same-asset refund branch, so the
ordinary proceeds outcome leaves it Open with its full principal and the
deadline reclaim later refunds money already spent out of other traders' pooled
reserve. That is a field someone forgot to set on one code path; here there is
no field to forget.

An unauthenticated execution cannot enter the lifecycle: VerifiedExecution is an
interface with an unexported method, so only VerifyExecution can produce one, and
Reserve takes nothing else. AcceptedBlock is the same shape, so a settle or
release can never be driven by a clock or a bare block id.

The reservation is keyed by CChain + CParent + ExecID — the parent OPPORTUNITY,
never a candidate block — so competing candidates all name one reservation and
none of them moves it.

FIX Latest externally, small internal vocabulary. ExecType (the event) and
OrdStatus (the resulting state) exist on the wire and are kept distinct per FIX;
they are never the internal source of truth. There is deliberately NO FIX state
for the provisional reservation — it is internal consensus machinery, and a
Trade is published only after C acceptance, which is what keeps the explorer's
CLOB honest.

15 tests, all passing: encoding injectivity over every field, domain separation,
verifier-supplied parent binding, terminal exclusivity, replay refusal.

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