Core Concepts: Ferum

A couple of core concept essential to understand Ferum

Fixedpoint Number

Ferum uses FixedPoint numbers consistently for all inputs into public and entry functions.

These numbers are interpreted to have fixed decimal places of 10 and a max value of MAX_U64 = 18446744073709551615.

Typed Parameters

Most Ferum contract instructions will require the I and Q type parameters. These type parameters represent the Aptos coin types for the pair being traded. Each Ferum market is identified by the pair, I/Q.

For example, if you want to place an order for APT/USDF, you would call:

add_order_entry<
    0x1::aptos_coin::AptosCoin, 
    0x7e9d4ebb1ac454c759719fc87b7f13b116d2f226c76d838970bf80e6aaea9000::test_coins::USDF
>(...)

In the above example, I is the fully qualified type name of APT (0x1::aptos_coin::AptosCoin) and Q is the fully qualified type name of USDF (0x7e9d4ebb1ac454c759719fc87b7f13b116d2f226c76d838970bf80e6aaea9000::test_coins::USDF).

I and Q can be any type used to create an Aptos coin. This means that a Ferum market can be created for any asset, making Ferum completely asset agnostic.

Decimal Precision

Each market specifies the max amount of decimal places supported for each asset in the pair. instrumentDecimals and quoteDecimals is how many decimals of precision the instrument asset and the quote asset support respectively.

The market's asset decimal precision must satisfy the following:

instrumentDecimals + quoteDecimals <= min(coin::decimals<I>(), coin::decimals<Q>())

Where​:

  • coin::decimals<I>: Decimals for the Instrument coin.

  • coin::decimals<Q>: Decimals for the Quote coin.

This constraint ensures that decimal overflow doesn't occur when processing orders.

Makers vs Takers

Similar to other exchanges, Ferum classifies orders as either maker or taker. A maker order is an execution that provides liquidity, while a taker order is an order that takes liquidity. For a more in-depth description, see this article.

An order is defined as a maker or a taker is defined at execution time. Each execution will have a maker side and a taker side. If the order being executed was resting on the orderbook, it is the maker order. If the order is executed immediately after being placed, it is the taker order.

The classification between maker and taker is important because it determines what fees the owner of the order is charged. See fees for more details.

Behaviours

Below are the type of behaviours Ferum supports.

  • GTC: A standard limit order. Can either be a maker or a taker.

  • POST: A limit order that can only be a maker order. If at the time of being placed, the order would be executed, it is cancelled.

  • IOC: Immediate or cancel. The limit order is cancelled if it is not fully filled immediately after being placed. Can result in partial executions.

  • FOK: Fill or kill. The limit order is cancelled if it is not fully filled immediately after being placed. Does not allow partial executions.

Ferum supports both market and limit orders. Market orders are denoted with price == 0.

Crank

Ferum relies on a crank to defer computation-heavy logic, such as cache/tree rebalancing, asset settlement, and resolution of pending quantities.

Order matching is still atomic and does not lead to a bad UX.

The cranker earns a portion of the user fee, ensuring that it is profitable to crank.

Anyone can call crank_entry and callers are rewarded proportional to the fees accrued by the instruction call.

Last updated