Getting data from pools
How to determine which token is token0 and which is token1?
The order of the tokens is determined in such a way that:
address(token0) < address(token1)
How to get address of liquidity pool?
To obtain the liquidity pool address, you can use one of the following methods:
1. Use poolByPair
mapping in AlgebraFactory
Documentation: poolByPair
Token addresses must be passed as parameters (in any order). If the pool exists, you will get its address. If such a pool has not yet been created, you will receive address(0)
.
2. Use computePoolAdress
function in AlgebraFactory
Documentation: computePoolAddress
Token addresses must be passed as parameters ( address(token0)
< address(token1)
). You will get address of pool even if it hasn't been created yet.
3. Calculate pool address using create2
mechanism
The previous options require making an external call to the AlgebraFactory contract. A cheaper option in terms of gas would be to calculate the address yourself. To do this, you can use the same logic as in method computePoolAddress
:
You need to know POOL_INIT_CODE_HASH
constant: you can get it from AlgebraFactory contract . POOL_INIT_CODE_HASH
It is important to note that the calculation uses the address not of the AlgebraFactory, but of the separate pool deployer contract (poolDeployer
), you also can get this constant from AlgebraFactory contract poolDeployer.
Also, important to remember that it is important to maintain the order of the tokens: address of token0 must be less than address of token1 (address(token0)
< address(token1)
)
Note: pool address calculation can be different in some blockchains (like zkSync Era).
Price
How to get current price in pool?
Information about the current instant price of the tokens in pool is in the globalState
structure:
And the safest way to get price and other data is to use special getter function:
You can get price directly from globalState
struct, but beware of read-only reentrancy, if you are doing it on-chain!
Next, it is important to understand what exactly is meant by price in liquidity pools. The pool stores the square root of the price of token0 relative to token1 in format Q64.96
. So, in pseudocode, price value in pool can be expressed as:
To get the usual instant price from the price value in the pool, you need to make the following transformations:
Further, if you need to bring the price to a human-readable form, it is necessary to take into account the difference in token decimals, if any.
Can i use "price" value in pool as real price?
Shortly: no, you should not rely on this raw value for anything other than internal pool calculations. This value in the pool reflects only its internal state at the current moment in time, can change and is subject to manipulation using swaps. In addition, when swapping, the actual execution price will differ from this value due to price impact and fee charged.
To get the real price of the swap, see the paragraph How to get actual execution price for swap?
If you need to get the average price in a pool for a certain period of time, then for this you can use data from a plugin with a TWAP-oracle, if it is connected to the pool.
How to get actual execution price for swap?
To do this, you can use a special peripheral contract called Quoter. For example, here is description of quoteExactInputSingle
:
You can do a static call to this method (and it is better not to use it on-chain due to gas costs). As a result, the number of tokens at the output and the real pool fee will be obtained.