Skip to content
Docs
Submit bugs here.
Docs

Please submit any typos you come across to GitHub issues.


Decentralized Exchange

In addition to supporting the issuing and movement of assets, the Stellar network also acts as a decentralized distributed exchange that allows you to trade and convert assets on the network. The Stellar ledger stores both balances held by user accounts and orders that user accounts make to buy or sell assets.

Orders

An account can create orders to buy or sell assets using the Manage Buy Offer or Manage Sell Offer operation. In order to initiate an order, the account must hold the asset it wants to use to buy (exchange for) the desired asset to be purchased. The account must also trust the issuer of the asset it’s trying to buy.

Orders in Stellar behave like limit orders in traditional markets. When an account initiates an order, it is checked against the existing orderbook for that asset pair. If the submitted order is a marketable order (for a marketable buy limit order, the limit price is at or above the ask price; for a marketable sell limit order, the limit price is at or below the bid price), it is filled at the existing order price for the available quantity at that price. If the order is not marketable (i.e. does not cross an existing order), the order is saved on the orderbook until it is either consumed by another order, consumed by a path payment, or canceled by the account that created the order.

Each order constitutes a selling obligation for the selling asset and buying obligation for the buying asset. These obligations are aggregated in the account (for lumens) or trustline (for other assets) owned by the account creating the order. Any operation that would cause an account to be unable to satisfy its obligations — such as sending away too much balance, will fail — This guarantees that any order in the orderbook can be executed entirely.

Orders are executed on a price-time priority, meaning orders will be executed based first on price; for orders placed at the same price, the order that was entered earlier is given priority and is executed before the newer one.

Price

Each order in Stellar is quoted with an associated price, and is represented as a ratio of the two assets in the order, one being the “quote asset” and the other being the “base asset”. This is to ensure there is no loss of precision when representing the price of the order (as opposed to storing the fraction as a floating-point number).

Prices are specified as a {numerator, denominator} pair with both components of the fraction represented as 32 bit signed integers. The numerator is considered the base asset, and the denominator is considered the quote asset. When expressing a price of “Asset A in terms of Asset B”, the amount of B is denominator (and therefore the quote asset), and A is the numerator (and therefore the base asset). As a good rule of thumb, it’s generally correct to be thinking about the base asset that is being bought/sold (in terms of the quote asset). (see comments below)

When creating a “buy”/“bid” order in Stellar via the Manage Buy Offer operation, the price is specified as 1 unit of the base currency (the asset being bought), in terms of the quote asset (the asset that is being sold). For example, if you’re buying 100 XLM in exchange for 20 USD, you would specify the price as {20, 100}, which would be the equivalent of 5 XLM for 1 USD (or \$.20 per XLM).

When creating a “sell”/“offer”/“ask” order in Stellar via the Manage Sell Offer operation, the price is specified as 1 unit of base currency (the asset being sold), in terms of the quote asset (the asset that is being bought). For example, if you’re selling 100 XLM in exchange for 40 USD, you would specify the price as {40, 100}, which would be the equivalent of 2.5 XLM for 1 USD (or \$.40 per XLM) (nice profit).

Fees

It’s important to note that the price you set is unrelated to the fee you pay for submitting the order as a part of a transaction. Fees are always paid in the native currency of the network (lumens), and are related to the transaction that you submit to the network (which contains your order operation) as opposed to your order itself.

For more information, take a look at our guide on fees in Stellar.

Passive Order

Passive orders allow markets to have zero spread. If you want to exchange USD from anchor A for USD from anchor B at a 1:1 price, you can create two passive orders so the two orders don’t fill each other.

A passive order is an order that does not execute against a marketable counter order with the same price. It will only fill if the prices are not equal. For example, if the best order to buy BTC for XLM has a price of 100XLM/BTC, and you make a passive offer to sell BTC at 100XLM/BTC, your passive offer does not take that existing offer. If you instead make a passive offer to sell BTC at 99XLM/BTC it would cross the existing offer and fill at 100XLM/BTC.

An account can place a passive sell order via the Create Passive Sell Offer operation.

Orderbook

An orderbook is a record of outstanding orders on the Stellar network. This record sits between any two assets. Abstractly, we often discuss assets using two fictional placeholder assets traded in a market, which we call ”wheat” and ”sheep”. The orderbook for that asset-pair therefore records every account wanting to sell wheat for sheep on one side and every account wanting to sell sheep for wheat on the other side.

(A bit of further market terminology: outside of Stellar, the concept of an “orderbook” normally contains two kinds of ”order”: buying is expressed by ”bid” orders, and selling is expressed by ”ask” orders, also called ”offers”. Within the Stellar network, the representation of orders is simplified: all orders are stored as selling — i.e. the system automatically converts all bids to asks in the opposite direction — and Stellar’s documentation and code can therefore sometimes be a bit lax in using the words “offer” and “order” as synonyms. Since both words refer to the same thing in Stellar in all cases, they are occasionally used interchangeably. This is harmless in the context of the Stellar ecosystem, but outside that context, an “offer” usually means an “ask” order specifically!)

An orderbook can be summarized by a diagram, as shown below. It is often visible on the trading interface of an exchange, though sometimes inverted left-to-right or drawn horizontally. But the idea is the same.

The diagram is split into two stacks of orders. Each stack is the set of orders related to selling an asset in a trading pair with the other asset. So at the top of the diagram there are the orders of people trying to sell sheep (or, equivalently, buy wheat). At the bottom there are the orders of people trying to sell wheat (or, equivalently, buy sheep).

For mnemonic purposes we’ve arranged the diagram with the sheep “on top” of the wheat here. If it helps you can picture a bunch of sheep standing on a field of wheat or some bushels of wheat, an arrangement less likely to cause chaos than trying to stack bushels of wheat on top of sheep.

Diagram of orderbook

Looking at the diagram, there are a few orientation things to notice and think about:

  1. Being willing to sell wheat for sheep is exactly the same as being willing to buy sheep for wheat. There are differences once we get into which direction of price movement you’ll accept as “better than your order”, but in general it’s just a question of which unit you declare the price and quantity for, so for uniformity sake, our order book encodes orders on both sides of a trading pair as selling.

  2. Generally more people will be willing to sell more of an asset at higher sale prices. This makes sense intuitively, an embodiment of the notion that “everybody has a price”. Not everyone will sell their favourite shoes for $100, but probably everyone will for $1,000 or \$10,000. Put another way: higher sale prices for an asset are “better” for people trying to sell it. If you’re selling at some price “or better”, that means “or higher prices”. (Equivalently: “or better” means “or lower price” for buyers, but again, we model both sides here as sellers). Similarly there is (intuitively) a lowest price at which anyone wants to sell an asset, and likely there aren’t many people who want to offer it at that cheapest price. So orders naturally “thin out” toward the center where it wouldn’t be especially appealing to bother selling, and “widen out” towards the edges where the prices (should they occur) would be tempting for lots of people to sell at.

  3. At any given moment, the order book (this diagram) contains all the orders that are notmatched”, i.e. that cannot be executed because the prices offered are not acceptably good to parties on either side to make a trade. Orders recorded in the book are the unmatched residue of orders submitted for trading. In other words, when someone submits a new order, the exchange matching engine will compare it to the orders in the book and execute any part it can, swapping assets from the parties involved and effectively deleting the intersection of the submitted order and the order book from both, writing only the symmetric difference of them back into the book. Orders that do match (and should be executed / symmetric-differenced) are also called ”crossing orders” (because they occur when the upper and lower parts of the diagram intersect, or cross), and sometimes this term is used as a verb, and the entire act of matching and executing is called ”crossing” a pair of orders/offers.

  4. Because the set of orders is not perfectly smooth — there is not necessarily every possible quantity of an asset on offer at every possible price — deleting the symmetric difference of matching orders is likely to open up a gap between the remaining cheapest offers (if there are any!) in either direction of the trading pair. This gap is the spread in the pair. The size of the spread will vary depending on quantity and variability of prices asked by sellers: a sparse or highly variably-priced set of offers will produce a bigger spread.

Some assets will have a very thin or nonexistent orderbook between them. That’s fine: as discussed in greater detail below, paths of orders can facilitate exchange between two thinly traded assets.

Cross-asset payments

Suppose you are holding sheep and want to buy something from a store that only accepts wheat. You can create a payment in Stellar that will automatically convert your sheep into wheat. It goes through the sheep/wheat orderbook and converts your sheep at the best available rate.

You can also make more complicated paths of asset conversion. Imagine that the sheep/wheat orderbook has a very large spread or is nonexistent. In this case, you might get a better rate if you first trade your sheep for brick and then sell that brick for wheat. So a potential path would be 2 hops: sheep->brick->wheat. This path would take you through the sheep/brick orderbook and then the brick/wheat orderbook.

These paths of asset conversion can contain up to 6 hops, but the whole payment is atomic—it will either succeed or fail. The payment sender will never be left holding an unwanted asset.

This process of finding the best path of a payment is called pathfinding. Pathfinding involves looking at the current orderbooks and finding which series of conversions gives you the best rate. It is handled outside of Stellar Core by something like Horizon. In foreign exchange this is often referred to as multi-leg and cross-currency transactions.

Preferred currency

Because cross-asset payments are so simple with Stellar, users can keep their money in whatever asset they prefer to hold. Preferred currency creates a very flexible, open system.

Imagine a world where, anytime you travel, you never have to exchange currency except at the point of sale. A world where you can choose to keep all your assets in, for example, Google stock, cashing out small amounts as you need to pay for things. Cross-asset payments make this world possible.

Last updated Sep. 13, 2021

Next Up: Federation
Page Outline