Orderbooks & Matching

Core to what makes Aver so innovative is the fact that the protocol operates a fully on-chain, multi-dimensional orderbook!

The General Case (Three or more outcome markets)

An Aver market consists of one-or-more orderbooks - though journaling and offsetting of matched and unmatched bets and determination of collateral requirements take place at market-level. (i.e. in a multi-outcome market, offsetting positions or mutually exclusive outcomes reduce collateral requirements).
That is to say, in the general case (3+ outcomes), there is a distinct set of 'bids' and 'asks' for each outcome in the market.
Depending on your background, you may be familiar with different language when it comes to discussing the orderbook.
Note the reference of 'bids' as limit orders to buy or 'back' the outcome, and 'asks' as limit orders to sell or 'lay' the outcome.
The on-chain representation of each orderbook works contains the following:
  • A 'bids slab' - A large Solana account which stores each of the live limit orders to back/buy a particular outcome.
  • An 'asks slab' - As above, but containing the sell/lay orders.
  • An 'event queue' - To which the matching process writes resulting actions which require deterministic execution elsewhere on the blockchain (i.e. in user accounts) to update or settle orders and positions.
For those interested in the implementation, to optimize for both space and memory on-chain, the bids and asks slabs store orders as nodes within in a highly optimized 'critbit tree', which can be traversed within the on-chain execution logic to facilitate posting, matching and removal of cancelled orders.

Two-Outcome ('Binary') Markets

In the case of a two-outcome ('binary') market, only one orderbook is required.
In a two-outcome/binary market, a bid on the first outcome is identical to an ask on the second outcome and vice versa. (i.e. to buy YES, is the same as to sell NO, if no other possible outcomes exist in the market).
For that reason, trades on the second outcome in the market are actually executed as a reversed trade on the first.
This is an example of cross-matching, which improves user experience. In some display formats (as inspired by traditional sportsbetting platforms) the same orderbook will be displayed as buy 'flipped' - so users will see both a buy/back and sell/lay option on both outcomes.
Within the SDK, the same orderbook is loaded twice and flipped so that the convention can be maintained across all markets (two outcome and three+ outcome markets).
Cross-matching is based on the principle that backing outcome 1 with probability
is the same as laying outcome 2 with probability

How Orders are Represented on the Orderbook

While the Aver application at app.aver.exchange facilitates orders and bets being displayed in multiple formats (Price/odds in Decimal, Probability or American; Size in Stake of Payout), the orderbook operates on the basis of:
  • Price stored in Probability format (i.e. in the range [0, 1])
  • Size stored in units of Payout
If your preference is to operate in another format, conversion between these values is simple:
  • Stake Size can be calculated as
    • Probability Price * Payout Size
  • Decimal Odds can be calculated as
    • 1 / Probability Price
  • American Odds can be calculated as
    • (100/(Probability Price))-100 if Probability Price <0.5
    • (100* Probability Price / (1 - (Probability Price))) * -1 if Probability Price >0.5

Price Tick Bucketing

Tick bucketing is implemented on Aver at the point when an order is first handled by the smart contract. Orders on the orderbook will contain prices which have already been conformed to the tick bucketing schema in operation for a given market.
Tick size (or price increment) refers to the minimum price movement in a market. The price movements of different trading instruments vary, with their tick sizes representing the minimum amount they can move up or down on an exchange.
This enables a degree of standardization in the structure of the orders on the order book, and avoids the frustrating scenario where participants can be continuously outbid by an infinitesimally small change in price.
You can read more about price tick bucketing here.
Currently, tick bucketing is applied in Probability Price terms, so the nearest ticks available to a participant who operates in Decimal or American odds terms may not appear so 'round'.
Following participant feedback, a solution is in the works which will enable markets to be configured to bucket in either Probability Ticks or Decimal Ticks in the very near future.
It is likely that the convention will be for Sports markets to be initialized in a 'Decimal-centric' schema, while other non-Sports prediction markets will default to a 'Probability-centric' schema.

Orderbook Execution Flow

Order Pre-processing

When an order is received by the smart contract, some initial validations are performed to determine whether the order is valid and whether the market is in an status where new orders are accepted.
The price provided is bucketed to the nearest available price 'tick'.

Matching attempted

General case - Limit Order

The validated and bucketed order is assessed against unmatched orders for this outcome on the opposing side of the orderbook. (i.e. an order to buy/back is assessed against available 'asks' orders to sell/lay, and vice versa)
Any orders which are at or more competitive than the price will be eligible to be matched. The execution logic iterates through each eligible order, ranked by price (most competitive to least) and sequence (the order in which it was posted).
The process continues to cycle through orders until either (a) the new orders desired size has been filled; or (b) there are no remaining eligible orders against which the new order can be filled.
If any residual amount of the order is unfilled, an order will be posted to the orderbook with the remaining size to be filled.

Alternative Order Types

A number of 'Order Types' are supported on Aver, which may distort the behavior of the general case (a 'Limit Order') which has been described above.
Other types of order include:
  • Immediate-or-Cancel (IOC) - This will match as much of the order as is currently available on the orderbook, but will not post any residual amount;
  • Fill-or-Kill (FOK) - This order will abort completely (i.e. fill nothing) if the order cannot be completed in full immediately based on current available orders;
  • Post-Only - This order will abort completely if it would cross the book / be matched with any existing orders.

Self-Trade Behavior

A self-trade occurs when a wallet places an order which would result in a match (or trade) against itself.
Orders accept a parameter - self_trade_behavior - which may distort the behavior of the general case (a 'Limit Order') which has been described above.
Self-Trade behavior parameter options are:
  • 'Decrement Take' - This approach will reduce the size of the current order and leave the existing (opposing) order owned by this wallet on the opposing side of the book.
  • 'Cancel Provide' - This approach will reduce the existing order (on the opposing side of the book).
  • 'Abort Transaction' - This will abort the entire transaction if a new order cross an existing order from the same wallet.

Updating Balances and Exposures

For the 'Taker' portion of an order

If some or all of the new order is matched, accounts are immediately updated for the to allow for the portion of the order that was filled in the matching process.
The tokens (i.e. USDC) required to fund the trade are transferred into the market's vault, and the User-Market account is updated to reflect the transfer of stake for exposures to a given outcome (in the case of a buy/back), or the receipt of stake in return for the negative exposure to a given outcome (in the case of a sell/lay).

For the 'Posted' portion of the order

If some or all of the order is posted to the orderbook (i.e. was unmatched), then the User-Market account is updated to reflect:
(a) That the user has an open order on one of the orderbooks, and the ID by which it can be identified;
(b) That the user has some 'locked' collateral which is required to be held to back the maximum collateral requirement that this order could lead to.
If tokens (i.e. USDC) are required to cover this potential collateral requirement, they are transferred into the market's vault at this time. Should the order go unmatched or be cancelled, the unused collateral is 'unlocked' and returned to the owner's wallet.

Settlement of the 'Maker' portion of a order

Every trade has two sides - each order which the new order is filled against leads to a need for that owner's UserMarket account to be updated too. Two types of 'events' can arise here - 'Fills' and 'Outs'.
The following scenarios will lead to a Fill, Out or both:
  • A Fill describes where a trade/match has been struck. It specifies the buyer and seller of the trade (i.e. the UserMarket accounts to be updated for settlement of the trade), the matching price and the quantity matched.
  • An Out describes an order which needs to be removed from a UserMarket account, because it has been removed from the orderbook, and to enable the 'unlocking' of any balances or positions that were being held as a result of this order remaining open on the book.
  • A Fill and Out would occur together where a match has resulted in the existing order being completed in full, or completed to the point where the residual quantity is below the threshold which would allow the order to remain on the orderbook.
A further transaction needs to occur to update the UserMarket account of the 'Maker' who has had a Fill, Out or Fill and Out generated in respect of their previously placed orders.
The orderbook matching logic writes these events (in deterministic order) to the orderbook's event queue. A separate process then sequentially addresses the necessary steps to settle (on-chain) the maker's UserMarket account:
  • Crediting for the proceeds of a Fill in terms of tokens received (in the case of a sell) or positions/exposures received (in the case of a buy)
  • Unlocking positions or balances which had previously been locked (in anticipation of backing the trade which has now been Filled or Outed), and if the result of a Fill (or proportion thereof) debiting the UserMarket for the part which has now been exchanged with another participant
  • Removing entirely from the UserMarket account the reference to an unmatched/open order which is no longer on the orderbook

Cranking the event queue

See section on cranking.