Econia contains a global
Registry that tracks information about markets, custodians, and underwriters, all of which can be registered permissionlessly.
An additional recognized markets registry provides additional functionality for certain markets that are recognized as following best practices for market size parameters.
Each Econia market is designated by a unique
MarketInfo and a corresponding serial market ID.
MarketInfo specifies the base and quote asset types for a market, as well as the corresponding market size parameters.
While the quote asset must be an
aptos_framework::coin::Coin, the base asset can be a
Coin or a "generic asset".
In the latter case, the base type is considered
GenericAsset, the market is registered with a corresponding generic base name, and a market-wide underwriter ID is specified, which indicates the serial ID of the underwriter required to verify generic asset amounts for the market.
Given that the
Registry is a global resource, access to it is gated in the interest of reducing of contentious transactions during runtime.
Hence market parameters are copied to
OrderBook structures to reduce lookup queries against the global registry, which could inhibit registration operations via colliding transactions.
To inspect info about a market from the
Registry in the general case, it should either be done off-chain or via the following functions:
First register a
MarketAccount under the corresponding market ID before calling either function.
Within a given market, a user may register a
MarketAccount where their signature is required to approve order operations and withdrawals.
They may also register additional market accounts, within the same market, under the authority of as many third-party custodians as they want.
The premier use case for a market account with custody delegated to a third party is margin trading, whereby custodians manage their own borrow/lend pools and cancel orders accordingly during liquidation events.
Custodians manage orders and withdrawals on behalf of a user, via a
CustodianCapability with a unique serial ID that is assigned upon issuance.
Via this custodian ID approach only a single entity (either signing user or a delegated custodian), has authority over a certain market account, such that access control can be gated across practically infinite market accounts within a given market.
For example, consider a user with the following market accounts:
|Market ID||Custodian ID||Authority|
As described in markets, an Econia market can have a
Coin type base asset or a "generic asset".
The premier use case for generic base assets is for derivatives markets, whereby it is impractical to publish a module with a new
Coin definition each time a market is to be registered.
Instead, for a derivatives market, Econia allows a third-party underwriter to verify generic asset amounts, which can then be traded from a user's
Here, a third party is required to underwrite amounts because unlike with
Coin assets, there is no public API that can verify the amount thereof:
when a user deposits
Coin assets to their market account, the
Coin.value getter function returns the amount deposited.
Conversely, for a non-
Coin asset an underwriter is required to certify the amount deposited to a
Underwriter operations are facilitated via an
UnderwriterCapability with a unique serial ID that is particular to a given market.
Here, an underwriter presides over asset amount verifications for an entire market, in the case of a generic market:
|Market ID||Underwriter ID||Asset amount verification authority|
A given base type and quote type combination is known as a
TradingPair, with a
MarketInfo containing the same fields as well as market size parameters, and in the case of a generic market, an underwriter ID.
Note that the
MarketInfo for a given market must be unique, but this does not mean that the
TradingPair for a market must be unique.
For example, Econia support registration of the following two pure coin markets:
|Base coin||Quote coin||Lot size||Tick size||Minimum order size|
|0.1 ||0.01 ||0.5 |
|0.01 ||0.01 ||0.05 |
|0.001 ||0.01 ||0.005 |
As a permissionless system, Econia allows market registrants to select whatever market size parameters they want, to provide for a frictionless registration experience if market conditions change:
USDC-denominated price of asset were to increase 100x, then a given lot size and minimum order size may no longer be appropriate, so here all one has to do is permissionlessly register a new market.
A potential result of this loosely-defined market uniqueness is liquidity fracturing: if two markets both have reasonable market size parameters, then market makers and takers may split liquidity between the two venues, leading to price discovery inefficiencies. To remedy this drawback, Econia additionally tabulates recognized markets.
Base asset types
Econia only supports
aptos_framework::coin::Coin-type quote assets, but base assets do not have to be a
This design enables spot markets, as well as derivatives markets where it is not practical to define a new
Coin type for each new market.
In the case of a spot market, where both the base asset and the quote asset are
Coin types, a new market can be registered via
register_market_base_coin_from_coinstore(), simply by passing in the base
CoinType as a type argument.
When registering a market where the base asset is not a
Coin type, a new market can be registered via
register_market_base_generic(), which instead requires passing in a string denoting the base asset name.
Note that this function also requires an immutable reference to an underwriter capability for the underwriter who will certify base asset amounts on the given market.
MarketInfo fields generated for the market then correspond to:
|Field||If base asset is coin||If base asset is not coin|
|Empty string||Name provided during registration|
In addition to a permissionless global
Registry, Econia also defines a
RecognizedMarkets structure that tabulates info for markets recognized as having proper market size parameters:
for a given
TradingPair there can be only one recognized market, such that, continuing the above example, only one
APT/USDC market may be considered recognized.
Registry, which is a contended global resource, the
RecognizedMarkets is almost always read-only, such that assorted getter functions can be used to look up the recognized market for a given
Here, users can simply decide what assets they want to trade, then look up the corresponding recognized market ID from the