AlcorDocs

Contract tables

Table structures of the order book DEX contract and the legacy AMM contract.

Tables of the order book DEX contract (alcordexmain on WAX, eostokensdex on EOS and Telos, alcor on XPR Network).

Markets

Table markets, scope: the contract account.

struct [[eosio::table]] market {
  uint64_t id;

  extended_symbol base_token;   // token prices are quoted in, e.g. WAX
  extended_symbol quote_token;  // traded token, e.g. TLM

  asset min_buy;   // minimum order amount in base_token
  asset min_sell;  // minimum order amount in quote_token

  bool frozen = false;
  uint8_t fee = 0;  // hundredths of a percent, 20 = 0.2%

  uint64_t primary_key() const { return id; }
  checksum256 get_secondary_1() const {
    return make256key(
      quote_token.get_contract().value,
      quote_token.get_symbol().code().raw(),
      base_token.get_contract().value,
      base_token.get_symbol().code().raw()
    );
  }

  // e.g. "TLM/WAX"
  string get_market_symbol() const {
    return quote_token.get_symbol().code().to_string() + "/" + base_token.get_symbol().code().to_string();
  }
};

typedef eosio::multi_index<"markets"_n, market,
  indexed_by<"bytokens"_n, const_mem_fun<market, checksum256, &market::get_secondary_1>>
> markets_index;

The bytokens index finds a market by its token pair. The key does not depend on token order:

uint128_t make128key(uint64_t a, uint64_t b) {
  uint128_t aa = a;
  uint128_t bb = b;
  return (aa << 64) + bb;
}

checksum256 make256key(uint64_t a, uint64_t b, uint64_t c, uint64_t d) {
  if (make128key(a, b) < make128key(c, d))
    return checksum256::make_from_word_sequence<uint64_t>(a, b, c, d);
  else
    return checksum256::make_from_word_sequence<uint64_t>(c, d, a, b);
}

A JavaScript version is make256key in alcor-ui/utils/index.js.

Orders

Tables buyorder and sellorder have the same structure. Scope: the market ID.

struct [[eosio::table]] buyorder {
  uint64_t id;
  name account;          // order owner
  asset bid;             // amount the owner gives
  asset ask;             // amount the owner wants
  uint128_t unit_price;  // price in base_token per quote_token, times 10^8
  uint32_t timestamp;    // seconds

  uint64_t primary_key() const { return id; }
  uint128_t get_price() const { return -unit_price; }  // sellorder: unit_price
  uint64_t get_account() const { return account.value; }
};

typedef eosio::multi_index<"buyorder"_n, buyorder,
  indexed_by<"byprice"_n, const_mem_fun<buyorder, uint128_t, &buyorder::get_price>>,
  indexed_by<"byaccount"_n, const_mem_fun<buyorder, uint64_t, &buyorder::get_account>>
> buyorders_t;

In a buy order bid is in the base token and ask in the quote token. A sell order is the other way round. The byprice index (index position 2, key type i128) returns the best orders first: highest price for buyorder, lowest for sellorder. The byaccount index (position 3, i64) filters by owner.

cleos -u https://wax.greymass.com get table alcordexmain 26 buyorder --index 2 --key-type i128 -l 10

Accounts

Table account, scope: the contract account. Counts open orders per owner.

struct [[eosio::table]] account {
  name account;
  map<uint64_t, uint16_t> buyorders;   // market_id -> open buy orders
  map<uint64_t, uint16_t> sellorders;  // market_id -> open sell orders
  uint16_t orders_total = 0;
  uint16_t orders_limit = 300;
};

Legacy AMM pairs

The first-generation AMM contract alcorammswap (WAX and Telos) keeps pools in table pairs, scope alcorammswap. Current pools are on swap.alcor.

struct [[eosio::table]] pairs_struct {
  uint64_t id;

  asset supply;          // LP token supply
  extended_asset pool1;
  extended_asset pool2;

  int32_t fee;
  name fee_contract;

  uint64_t primary_key() const { return id; }
  checksum256 secondary_key() const {
    return make256key(
      pool1.contract.value, pool1.quantity.symbol.code().raw(),
      pool2.contract.value, pool2.quantity.symbol.code().raw()
    );
  }
};

typedef eosio::multi_index<"pairs"_n, pairs_struct,
  indexed_by<"extended"_n, const_mem_fun<pairs_struct, checksum256, &pairs_struct::secondary_key>>
> pairs_index;

On this page