Ticks, Ratios, and Prices
Ticks
A tick on Mangrove represents a discrete point in the price space of a market. Rather than allowing continuous prices, Mangrove divides the space into fixed increments, each tick corresponds to a 0.01% (1 basis point) change in price.
This discrete representation allows for precise, gas-efficient price calculations and easy integration with on chain logic.
Formally:
A higher tick value represents a higher price on the ask side and lower price on the bids side.
Ratios
In Mangrove, every offer is defined not directly by a "price", but by a ratio. The relationship between the amount offered and the amount requested:
This ratio determines how much of a token is received for a given amount of another. It's the fundamental internal measure of price used throughout the protocol and codebase, ensuring consistency across all token pairs.
The Relation Between Ticks and Ratios
Ticks and ratios are directly linked: each tick corresponds to one unique ratio, and each ratio can be expressed as a tick using a logarithmic function:
This relationship allows prices to be converted between human-readable form and the compact on-chain tick representation
The meaning of a ratio depends on whether the offer is on the asks or bids side of a market.
Asks side, selling the base token, receiving the quote tokens:
Bids side, buying the base token, giving the quote tokens:
This distinction ensures consistent logic across both side of the book, even though mathematical expressions are inverted.
Example: In a WETH/DAI market (prices expressed in DAI per WETH):
On the asks side (selling WETH), price = wants/gives = 2,224 DAI/WETH.
On the bids side (buying WETH), price = gives/wants = 0.0004496 WETH/DAI.
Prices, Decimals, and Raw Values
All ERC-20 token amounts are stored on-chain as integers, often called raw values. Each token defines its own number of decimals, and Mangrove ignores these decimals internally for consistency.
USDC
6
87654321
87.654321
DAI
18
876543210987654321
0.876543210987654321
WETH
18
109876543210987654321
109.876543210987654321
:::
To display human-readable prices, the SDK or UI must account for the difference in decimals between the base and quote tokens.
The conversions between raw ratios & prices and their user representations are:
This ensures correct display of "real-world" prices, even when token decimals differ.
Example:
Market
Token Decimals
Ask (quote/base)
Ask ratio (raw)
Bid (base/quote)
Bid ratio (raw)
DAI/USDC
DAI = 18 USDC = 6
WETH/DAI
WETH = 18 DAI = 18
Beware decimals! As an important example of the implications, note that while the price space contains the raw price 1, it may not contain the user readable price 1. This is likely if base and quote have different numbers of decimals.
Converting Prices and Ticks
Because the price space is discrete, not every price maps exactly to an integer tick. When converting a price to a tick:
The resulting tick is then rounded:
Takers usually round down, ensuring they never pay more or receive less than expected.
Makers usually round up, ensuring they never receive less or sell for too little.
Tick Spacing
Mangrove allows each market to define a tickSpacing parameter, controlling how dense the available price points are. Only ticks where:
are valid for offer in that market.
Example:
With tickSpacing = 5 , valid ticks are ..., -15. -10, -5, 0, 5, 10, 15,... The smallest price increment is then:
Ranges
Mangrove supports a wide range of ticks, allowing for extremely high or low prices:
Tick
-887,272
887,272
Ratio
Price
The TickLib Library
Mangrove provides a Solidity library called TickLib which includes:
Functions to convert between ticks, ratios, and prices.
Utilities for rounding ticks appropriately for maker or taker use.
Helpers for computing inbound/outbound volumes at specific tick levels.
Comparison to Uniswap Ticks
Mangrove's ticks are inspired by Uniswap V3 ticks, but with the following notable differences:
It operates directly on ratios (not √ratios), simplifying computation.
Ratios are handled as floating-point numbers, improving precision.
Last updated