mirror of
https://github.com/luxfi/dex.git
synced 2026-09-24 00:26:31 +00:00
C and D each own value while it is on that chain, and a unit is spendable on exactly one of them at a time: C --Export--> C_TO_D --Import--> D --Export--> D_TO_C --Import--> C Those four transitions and no others. Never C to D directly, which would mean a moment where value is in both places or neither. The consequence is the point. Once imported, D is not matching against hypothetical C collateral — it has real balances, and every order, match and trade is a local movement. A million trades cost zero boundary crossings. That is what makes D an exchange ledger rather than a remote matching oracle attached to C. So the atomic rail is narrowed to one job: move ownership exactly once. It knows nothing about orders, executions, trades or settlement. The per-trade cross-chain certificate, the C-parent reservation and the accept-or-release round trip stay only for the V4 adapter, where a contract genuinely demands synchronous C composability. Import consumes and credits in one operation. Splitting them either destroys value or lets a retry, a reorg, a racing relayer or a restart import the same object twice, which is a double-spend of real money. Refusal is loud rather than silent — a caller that imported twice has a bug worth seeing. Export draws only on available balance, so value committed to an open order cannot also leave the chain. A claim names its beneficiary, which is what makes import safely permissionless: delivering one can only credit the account it already names. Co-location buys latency, never correctness. Execution now carries MarketVersion and the exact token amounts D resolved, so C verifies amounts rather than recomputing lots from whatever the market says now — recomputing would replay a block to a different result after a market update. Price is gone; it was Output over Input stated twice inside a signed struct. Partial execution is bounded by cross-multiplication, executionOutput * orderInput >= executionInput * orderMinOutput, so there is no division, no rounding convention, and the rule composes: if every slice satisfies it, so does their sum. 60 tests. Conservation asserted after all 600 operations of a random run: imported 4143, exported 2576, D owns 1567. Co-authored-by: Hanzo Dev <[email protected]>