Skip to main content

Uniswap V3

Uniswap V3 ETH/USDC liquidity pool on Arbitrum:

This example tracks the price of the ETH/USDC Uniswap V3 liquidity pool on Arbitrum:

Loading...

Which displays prices emitted by the below script:


onBlock(block => {
for (const rootTx of block.getTransactions()) {
for (const tx of rootTx.flattenChildren({
// Arbitrum WETH/USDC liquidity pool
// https://www.geckoterminal.com/fr/arbitrum/pools/0xc31e54c7a869b9fcbecc14363cf510d1c41fa443
contract: '0xc31e54c7a869b9fcbecc14363cf510d1c41fa443',
// we're only interested in calls, not static calls
onlyOp: 'CALL',
})) {
// get reserves
const {sqrtPriceX96, x, y, xDec, yDec} = getPriceData(tx.to);

// compute price, as a numeric value
// see https://ethereum.stackexchange.com/questions/98685/computing-the-uniswap-v3-pair-price-from-q64-96-number
const numerator1 = sqrtPriceX96 * sqrtPriceX96;
const price = numerator1 * (10n ** 18n) / (2n ** BigInt(96 * 2));
const p = Number(price) / (10 ** (18 + Number(yDec - xDec)));

// send !
emit({
t: block.timestamp,
pool: tx.to,
blockNumber: block.number,
x,
y,
priceXY: p,
priceYX: 1/p,
});

// we dont care if there is more than 1 tx on this block
return;
}
}
})

const {Main:{getPriceData}} = solidity<Pricing>`
pragma solidity ^0.8.15;

// see https://github.com/Uniswap/v3-core/blob/main/contracts/interfaces/IUniswapV3Pool.sol
// - https://github.com/Uniswap/v3-core/blob/main/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol
// - https://github.com/Uniswap/v3-core/blob/main/contracts/interfaces/pool/IUniswapV3PoolState.sol
interface IUniswapV3Pair {
function slot0()
external
view
returns (
uint160 sqrtPriceX96,
int24 tick,
uint16 observationIndex,
uint16 observationCardinality,
uint16 observationCardinalityNext,
uint8 feeProtocol,
bool unlocked
);
function token0() external view returns (address);
function token1() external view returns (address);
}

interface IERC20 {
function decimals() external view returns (uint256);
}

contract Main {
function getPriceData(IUniswapV3Pair pool) public view returns (
uint160 sqrtPriceX96,
address x,
address y,
uint256 xDec,
uint256 yDec
) {
(sqrtPriceX96,,,,,,) = pool.slot0();

x = pool.token0();
y = pool.token1();

xDec = IERC20(x).decimals();
yDec = IERC20(y).decimals();
}

}`;