ViteX is a built-in decentralized exchange on the Vite chain and an important component of the Vite ecosystem. ViteX consists of Vite’s built-in contract, vDex, and the off-chain service, dexServer.
vDex was originally designed to perform all of the exchange’s core functions on-chain, such as deposits, withdraws, listing trading pairs, and order matching. However, subsequent on-chain functions such as the mining of VX coins, fee dividends and operator management have been included as well. Needless to say, all these functions are implemented with security and full transparency of rules in mind.
The following is an introduction to several key points in the design and implementation of vDex.
Particular to vDex’s implementation (as compared to that of other centralized exchanges) is the storage structure enhancements and performance of the chain itself. To maximize match efficiency, vDex has adopted multiple optimization strategies for read/write efficiency.
The method by which orders are stored determines the read/write efficiency, and ultimately determines the order-matching efficiency.
At the lowest level, the Vite chain employs a LevelDB-like storage. It supports sequential traversal ordered by byte, which is consistent with vDex’s Taker-Maker matching rules. These rules do matching according to the price rank of trading orders. vDex uses an order ID format that complies with levelDB’s ordering mechanism, ensuring that Taker-matching takes only one iteration to complete.
The order structure is presented below:
The order id is a 22-byte field composed of the following subfields:
marketId: a unique identifier for each trading pair. This is auto-incremented.
side: 0 or 1 for Buy/Sell respectively. It is a 1-byte suffix to marketId. A Taker order will scan all pending Maker orders with the same prefix during a matching process.
price: a 10-byte long fixed-point number. The first 5 bytes correspond to the integer portion, and the last 5 bytes to the fractional portion. This can support a maximum length of 12-digit integer and 12 decimals. For a sell order, prices are stored normally from low to high, whereas in a buy order, the value is flipped to represent a reversed price order from high to low.
timestamp: orders with the same price are sorted by timestamp.
serialNo: for orders with the same price and timestamp, orders are sorted according to the sequence by which the orders were confirmed on the chain, ensuring a strict order.
This 22-byte long order id serves as a key for levelDB traversal, thus providing efficient order traversal by price.
The matching engine generates a new prefix from the combination of Taker’s marketId+!side. It uses this prefix to traverse through levelDB in ascending order, thus generating a list of all ranked orders in the market placed by Makers. A Taker’s order is matched when the following conditions are met: !taker.side && bytes.cmp(taker.price, maker.price) >= 0 || taker.side && bytes.cmp(taker.price, maker.price) <= 0. Any unmatched remainder is further processed until either the match fails or the transaction is completed. When a match fails, the taker’s order ID is sent to storage. The entire matching process adopts a simple and efficient way of reading/writing storage.
Order object compression
To improve storage efficiency, protocol-buffers are used to serialize the order object. If sufficient compression can be guaranteed, new fields may be added to the order structure to enhance backward compatibility.
Storage can further be optimized by nulling the order ID’s four fields (marketId, side, price, and timestamp) prior to deserialization. During deserialization, only relevant fields are assigned.
Storage clean up
To further reduce the occupation of on-chain storage, space is cleaned for completed matches and cancelled orders. Orders have a set timeout mechanism. Expired orders can be cancelled in batches without verification. To ensure all orders are accessible, cleared orders are persisted in dexServer service off the chain.
Mining/dividend metrics storage optimization
vDex supports on-chain trade mining, stake mining, and handling of fee dividends. At the end of a day-by-day period, mining/dividend results are produced based on relevant metrics for the period.
To avoid unnecessary impacts on normal transactions, mining and increase of period are made asynchronous. This requires that the state at the end of each period can be traced back via, in vDex’s implementation, snapshot blocks. To minimize the number of snapshots, a new period is recorded only when there is a difference with a previous valid period, which minimizes storage duplication.
The current version of vDex consists of two built-in contracts: dexFund undertakes operations such as deposits, withdraws, listing trading pairs, order placement, mining, dividends, etc… and dexTrade completes the actual pending order, be it a match or a cancel.
The design of two separate contracts facilitates system splitting and maintenance from an engineering perspective, and facilitates subsequent dexTrade sharding for higher throughput.
Asset correctness check
Correctness at code level is ensured through both unit testing and integration testing.
vDex also verifies asset consistency in real time by comparing all the assets in a contract to the actual balance of the contract on the chain. If they are consistent, errors due to internal calculation and logic errors resulting in excessive asset issuance or loss can be ruled out.
Asset check is equivalent to performing a full integration test on all the code of vDex’s contracts. This operation can be performed periodically during test phase or after formal deployment to verify the correctness of the contracts.
vDex and dexServer collaboration
During the execution of the contracts, internal states are modified. Internal state changes are recorded in a eventLog and handled by off-chain service dexServer, allowing piping to downstream services such as monitoring and data statistics services.
ViteX Official: https://vitex.net/
Vite Forum: https://forum.vite.net
- English: https://t.me/vite_en
- Chinese: https://t.me/vite_zh
- Russian: https://t.me/vite_russian
- Korean: https://t.me/vite_korean
- Japanese: https://t.me/vite_japanese
- Vietnamese: https://t.me/vite_vietnamese
- Thai: https://t.me/vite_thai
- Arabic: https://t.me/vite_arabic
- German: https://t.me/vite_german
- French: https://t.me/vite_french
- Turkish: https://t.me/vite_turkish
- Indonesian: https://t.me/vite_indonesian
- Spanish: https://t.me/vite_spanish
- Malaysian: https://t.me/vite_malaysian
- Filipino: https://t.me/vite_filipino
- Bengali: https://t.me/vite_bengali
- Sri Lankan: https://t.me/vite_sri_lankan