Assetera Docs
Smart contracts

Order lifecycle

The AsseteraExchange order state machine (place, fill, settle, cancel and expire), and what each step escrows and attests.

An order is a maker's standing intent to trade one token for another. The maker escrows the token they're selling up front; takers fill against it, and the trade finalizes either by a counterparty fill or by an operator settling two complementary orders. Orders are 1-indexed (getOrder(id) reads one; totalOrders() is the high-water mark).

State machine

The on-chain OrderStatus enum is: None, Open, Filled, Settled, Cancelled, Refunded, ForceCancelled, Expired. A newly placed order is Open; every terminal transition emits exactly one lifecycle event.

Placing an order

placeOrder(sellToken, sellAmount, buyToken, buyAmount, expireTs, att) escrows sellAmount of sellToken and records the desired buyToken / buyAmount. It requires a valid KYC attestation for the Place action and snapshots the fee terms (makerFeeBps, takerFeeBps, feeCollector) onto the order, immutable thereafter. expireTs of 0 means the order never expires. It emits OrderPlaced and returns the new order id.

placeOrderWithPermit(...) is the same call with an ERC-2612 permit attempted first (best-effort, swallowed on failure) so the maker can approve and place in one transaction.

Filling an order

fillOrder(id, fillSellAmount, att) lets a taker trade against an open order, requiring a KYC attestation for the Fill action. Fills can be partial or full:

  • Partial (order still has remaining quantity afterwards) emits OrderPartiallyFilled and the order stays Open.
  • Full (remaining quantity reaches zero) emits OrderFilled and the order becomes Filled.

Fees are deducted from the gross amounts before each party receives funds: the maker fee comes out of the maker's buy-side receipt, the taker fee out of the taker's sell-side receipt, both routed to the allowlisted feeCollector. The buy-side amount is ceiling-divided so the maker never loses to rounding.

Settling two orders

settle(buyId, sellId, attBuy, attSell) is an operator action (OPERATOR_ROLE) that matches two complementary orders and moves both to Settled, zeroing both remaining quantities. It requires a fresh KYC attestation from both makers for the Settle action: the operator cannot settle on a maker's behalf without their signed consent. It emits OrderSettled with the settled amounts and both fee legs.

Roadmap: on-chain operator settlement is being parked; standard operations will not settle on chain. settle, settleOffer and refund are moving out of the production standard flow (kept for possible re-enable via upgrade). Treat operator settlement as present-in-testnet but not part of the production baseline.

Cancelling

The maker can cancel their own open order and reclaim the escrowed remaining quantity, emitting OrderCancelled. On the current testnet there are two paths: cancelOrder(id, att) (KYC-gated) and cancelOrderSelf(id) (no attestation). They emit the same event and can only be distinguished by whether a KycConsumed event appears in the same transaction.

Roadmap: these two cancel paths are being consolidated into a single always-unattested cancelOrder(id): a user must always be able to cancel their own open order and reclaim escrow without needing an attestation.

Expiry and sweeping

An order past its expireTs is dead but its escrow is still locked until swept. sweepExpired(ids[]) is permissionless and batched (≤100 ids). It refunds each expired order's remaining quantity to the rightful maker (not the caller), silently skipping ineligible ids, and emits one OrderExpired per swept id. Anyone can sweep a user's expired orders on their behalf.

Roadmap: automatic sweeping (so escrow is auto-returned without a manual call) is planned.

Escape hatches

Two admin-gated exits move escrow when a maker can't act for themselves: refund(id, reason) returns remaining escrow to the maker (OrderRefunded), and cancelOrderForUser(id, recipient) force-cancels an open order to a compliance-directed recipient (OrderForceCancelled). Together with the sweeps, these are the only ways escrow leaves the contract without a matching fill or settlement.

On this page