Skip to content
Zeno Docs

Subgraph reference

The subgraph indexes ZenoLOP's events into a queryable order book with two entities, Order and Payout.

Order

An entry order submitted by a maker. It stays OPEN until the maker cancels it, which is only possible at or after expiry. Fills are tracked as separate Payout entities.

type Order @entity(immutable: false) {
  id: Bytes!
  orderId: BigInt!
  maker: Bytes!
  mpk: Bytes!
 
  makingTokenType: Int!
  makingTokenAddress: Bytes!
  makingTokenSubID: BigInt!
  makingAmount: BigInt!
 
  takingTokenType: Int!
  takingTokenAddress: Bytes!
  takingTokenSubID: BigInt!
  takingAmount: BigInt!
 
  listProviderPPoIKey: Bytes!
  expiry: BigInt!
  status: OrderStatus!
 
  allocatedAmount: BigInt!   # sum of payoutAmount across all fills
  remainingAmount: BigInt!   # takingAmount - allocatedAmount; zeroed on cancel
  refundedAmount: BigInt     # unallocated remainder returned on cancel
 
  createdAtBlock: BigInt!
  createdAtTimestamp: BigInt!
  createdTxHash: Bytes!
 
  cancelledAtBlock: BigInt
  cancelledAtTimestamp: BigInt
  cancelledTxHash: Bytes
 
  payouts: [Payout!]! @derivedFrom(field: "order")
}

Order accounting is reconstructed from events: allocatedAmount accumulates each fill's payout, and remainingAmount is the escrow still unallocated.

Payout

A payout created when an order is filled. The note has already been delivered to the maker; the filler must claim within the window, otherwise the maker may reclaim the escrow.

type Payout @entity(immutable: false) {
  id: Bytes!
  payoutId: BigInt!
  order: Order!
 
  recipient: Bytes!       # where the payout is sent on a successful claim
  payoutAmount: BigInt!   # takingToken owed to the filler
  noteAmount: BigInt!     # makingToken delivered to the maker
  commitment: Bytes!      # delivered note commitment
  deadline: BigInt!       # last timestamp the filler can claim
 
  status: PayoutStatus!
  random: Bytes           # blinding revealed on a successful claim
  reclaimedBy: Bytes      # maker that reclaimed the escrow
 
  createdAtBlock: BigInt!
  createdAtTimestamp: BigInt!
  createdTxHash: Bytes!
 
  resolvedAtBlock: BigInt
  resolvedAtTimestamp: BigInt
  resolvedTxHash: Bytes
}

Status values

EnumValues
OrderStatusOPEN, CANCELLED
PayoutStatusPENDING, EXECUTED, RECLAIMED

A payout moves from PENDING to EXECUTED when the filler claims (revealing random), or to RECLAIMED when the maker recovers the escrow after the deadline.

Finding fillable orders

query OpenOrders($now: BigInt!) {
  orders(
    where: { status: OPEN, remainingAmount_gt: 0, expiry_gt: $now }
    orderBy: createdAtTimestamp
    orderDirection: desc
  ) {
    id
    orderId
    mpk
    makingTokenAddress
    makingAmount
    takingTokenAddress
    takingAmount
    remainingAmount
    expiry
    listProviderPPoIKey
  }
}

Indexed events

OrderCreated, OrderCancelled, OrderFilled, PayoutExecuted, and PayoutReclaimed. See the contract reference for their signatures.

Keeping it in sync

After changing the contract, regenerate the ABI and rebuild, then redeploy:

jq '.abi' out/ZenoLOP.sol/ZenoLOP.json > subgraph/abis/ZenoLOP.json
cd subgraph && npm run codegen && npm run build

Set the deployed address, network, and start block in subgraph/networks.json and subgraph.yaml before deploying. See the quickstart.