AXIS Docs

Using AXISCore concepts

Markets and prices

A market is a pair of assets on the DEX. Learn how markets open, how the app shows prices, what the oracle does and how swaps cross several markets.

What a market is#

Two assets define a market pair, such as XLM and USDC. Both directions share the same market: selling XLM for USDC and selling USDC for XLM are the two sides of the same XLM/USDC orderbook. The contract keeps one market record per pair, whichever way you name it.

Base and Quote#

Apps show a market as BASE/QUOTE. Prices are in the quote asset per one unit of the base asset, and amounts are in the base asset. On the XLM/USDC market a price of 0.25 means 0.25 USDC per XLM, "Buy" means buying XLM with USDC, and "Sell" means selling XLM for USDC.

This orientation is only for display. The contract stores every order as "sell this asset, receive at least this much of the other per unit", and converts a buy order to that form. A stored order's price is always in units of the asset it buys per unit of the asset it sells.

New market creation#

Anyone can open a market, and no approval is needed. The opener calls the contract's subsidize function and pays a listing fee in XRF, the utility token of the Reflector oracle. The fee is the oracle's daily fee times the number of days of price feeds a new market must buy, a contract setting that is 90 days by default. With 90 days, the fee buys 90 days of oracle price feeds for the pair, or 45 days for each asset when the oracle quotes both. The XRF tokens are burned when received by the oracle.

At least one of the two assets must be quoted by the oracle, otherwise the market cannot open. Anyone can later call subsidize again with more XRF to extend the price feeds of an existing market.

The safety admin has no function to open, close or delist markets. Only limit orders and order updates need an open market, see Which actions need a market. Fees and costs explains who pays the listing fee.

Note

On Testnet the listing fee is currently set to 18,000 XRF per market.

What the oracle is used for#

AXIS uses the Reflector oracle for two things only:

  • Deciding which pairs can host limit orders. A market needs at least one asset the oracle quotes. This guards the DEX from wash-trading and trash tokens.
  • Enforcing the minimum order value. The contract estimates the USD equivalent volume for each limit order based on the oracle price, see Minimum order value.

The oracle never sets the price of a fill. Fills always happen at the maker's price, which traders choose. A wrong oracle price cannot make you buy or sell at a different price.

Price freshness#

Trades never call the oracle directly. Instead, the contract keeps a cached copy of each asset's oracle price, and a cached price is usable for up to 72 hours after if was obtained from the oracle.

Keeping prices fresh is the job of keepers. They call the contract's permissionless requote function for an active market. Fetching new prices also requires the market's oracle access, purchased with XRF through the subsidize call. See Running a keeper.

When a market's cached price goes stale:

  • New limit orders and order updates pause. They fail with "No recent oracle price for this market" until a keeper refreshes the price.
  • Fills, market orders, swaps, crossfills and cancels keep working.

If the oracle no longer quotes either of a market's assets, the market stops accepting new limit orders and order updates once a keeper refreshes it. Existing orders stay fillable, and their owners can still cancel them.

Which actions need a market#

Action Needs an open market Needs a fresh oracle price
Limit order Yes Yes
Order update Yes Yes
Market order No No
Fill-or-Kill order No No
Swap No No
Crossfill No No
Cancel No No

Market orders, swaps and crossfills fill existing orders, so in practice they trade on open markets too, but they keep working when prices go stale. A fresh oracle price is needed only while a minimum order value is configured. A cancel works even on a market whose assets the oracle no longer quotes, while an order update on such a market fails.

Swaps across several markets#

A swap trades one asset for another through a route of one or more markets in a single transaction. For example, XLM to EURC can go directly through the XLM/EURC market, or through USDC: XLM to USDC on one market, then USDC to EURC on another. The AXIS API looks for routes of up to three markets (hops) and returns the best ones.

Each hop fills orders on one market. The makers of each hop deliver to the contract, which pays the next hop with those tokens and sends what the last hop bought to you in one transfer. The contract holds them only inside the transaction. You choose one of two modes:

  • Exact input. You pay the amount you enter, and receive at least a set minimum.
  • Exact output. You receive exactly the amount you enter and pay at most a set maximum.

The contract plans the whole route before moving anything. If the route cannot meet your minimum or maximum, the swap fails and nothing moves. A route can fill at most 20 orders in total per one transaction. Every asset a route buys passes through the contract, so an asset whose issuer requires authorization can be bought only after the issuer has authorized the AXIS contract. Routes use AXIS orders only, not Classic DEX offers or AMM pools. The trading guide shows how to swap in the AXIS app.

Orderbook depth#

An order is only as good as its maker's balance and allowance (see Order backing). The AXIS API therefore counts only the backed part of each order in the orderbook, the depth chart and quotes. If a maker lists 1,000 USDC for sale but holds only 400 USDC, the book shows 400 USDC. This is an effective depth. It shows what makers can actually deliver, as far as the indexer can tell from their latest balances and allowances.

Crossed books#

Normally the best bid is below the best ask. On AXIS the book can be crossed from time to time, with a bid above an ask, because the contract only matches the orders a trader lists. A limit order placed without listing a cheaper opposite order stays on the book even though the two prices cross.

A crossed book is an opportunity. Anyone can call the contract's crossfill function to match the crossing orders, pay both owners at least their own prices and keep the difference. See Crossed orders and crossfill for an example, and Markets and oracle for the developer details.