How ZenoLOP works
The problem it solves
Moving value into a RAILGUN shielded pool costs an entry fee, and moving it out costs an exit fee. A trader who shields and later unshields pays both.
ZenoLOP removes that cost by pairing opposite flows. If one party wants to enter the pool while another wants to exit, the entrant's public tokens can pay the exitant directly, and the exitant's shielded funds can be delivered to the entrant as a note inside the pool. Nothing is shielded or unshielded, so neither fee applies. What would have been two fee-paying trips across the boundary becomes one atomic swap.
Roles
- Maker - wants to end up inside the pool. Escrows public ERC20 (
takingToken,takingAmount) and specifies the shielded note they want delivered (makingToken,makingAmount) plus the pool key (mpk) that must be able to spend it. - Filler (taker) - is already inside the pool. Delivers the requested note to the maker via a RAILGUN transaction and collects the escrowed public tokens, minus the taker fee.
Order lifecycle
maker: submitOrder ───> EntryOrder created, takingAmount escrowed in the contract
│
filler: fillOrder ────────┤ RAILGUN transact delivers note(s) to the maker; per fill the contract
│ verifies the note proof, decrements remainingAmount, and creates a
│ PendingPayout with deadline = now + claimWindow
│
filler: claimPayout ──────┤ within the claim window: reveal the note blinding
│ ──> escrow released to the recipient, minus the taker fee
│
maker: reclaimPayout ────┤ after the deadline, if unclaimed ──> escrow returns to the maker
│
maker: cancelOrder ──────┘ at or after expiry only ──> unallocated remainder refunded
Submitting
submitOrder takes custody of the full takingAmount up front, so an order is always fully funded.
It requires both amounts to be non-zero and the expiry to be in the future. A balance-delta check
rejects fee-on-transfer tokens, and only ERC20 is supported.
Filling and partial fills
An order can be filled by several fillOrder calls until its remainingAmount reaches zero. Each
delivered note pays out pro-rata:
payout = deliveredNoteAmount * order.takingAmount / order.makingAmount
The division is floored, so rounding dust favors the maker, whose escrow funds the payout. A fill that rounds down to zero is rejected as "Fill too small". Each note commitment can only be used once.
A fill whose payout exceeds the order's remainingAmount reverts on the subtraction with an
arithmetic panic (Panic(0x11)), not a named error, so there is no revert string to match on. This
is the ordinary outcome of losing a race for the same order. Size fills against the current
remainingAmount and treat a bare panic as "another filler got there first".
Two-phase settlement
Filling does not immediately release the escrow. fillOrder creates a PendingPayout with a
deadline of now + claimWindow, and settlement completes only when the filler calls claimPayout
within that window, revealing the note blinding.
Revealing the blinding is what ties the claim to the note that was actually delivered: the contract
recomputes the commitment from the order's mpk, the delivered note amount, and the blinding, and
requires it to match.
The window exists to bound how long escrow stays earmarked against a fill. A filler who delivers a
note but never claims would otherwise strand that portion of the maker's escrow indefinitely;
instead the deadline passes and reclaimPayout returns it to the maker. It is a liveness guarantee,
not a check on the filler: nothing about the delivered funds is validated at claim time beyond the
blinding match.
Cancelling
cancelOrder refunds whatever escrow has not been allocated to fills. It is restricted to the maker
and, notably, is only permitted at or after the order's expiry. An order cannot be withdrawn
early: until it expires it stays fillable.
Fees
A takerFee of 10 basis points (0.1%) is skimmed from each payout and sent to the treasury. The
filler receives the remainder. The fee is a compile-time constant; the treasury address and the claim
window are owner-settable.
Related
- Binding and proofs - how fills are made safe.
- Contract reference - the exact interface.