Contract Name:
Uniswap3Data
Contract Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface Uniswap3SC{
function liquidity() external view returns (uint128);
function tickSpacing() external view returns (int24);
function slot0() external view returns (
uint160 sqrtPriceX96,
int24 tick,
uint16 observationIndex,
uint16 observationCardinality,
uint16 observationCardinalityNext,
uint8 feeProtocol,
bool unlocked
);
function ticks(int24 tick) external view returns (
uint128 liquidityGross,
int128 liquidityNet,
uint256 feeGrowthOutside0X128,
uint256 feeGrowthOutside1X128,
int56 tickCumulativeOutside,
uint160 secondsPerLiquidityOutsideX128,
uint32 secondsOutside,
bool initialized
);
function token0() external view returns (address);
function token1() external view returns (address);
}
contract Uniswap3Data{
struct TickRange {
int24 lower;
int24 upper;
}
function calculateTickRange(int24 tick, int24 tickSpace) internal pure returns (TickRange memory range) {
if(tick >= 0){
range.lower = int24(int256(tick / tickSpace) * tickSpace);
range.upper = range.lower + tickSpace;
}else{
if(tick % tickSpace != 0){
range.upper = int24(int256(tick / tickSpace) * tickSpace);
range.lower = range.upper - tickSpace;
}else{
range.lower = tick;
range.upper = tick + tickSpace;
}
}
return range;
}
struct LiquidityNetData{
int24 tick;
int128 liquidityNet;
}
struct LiquidityNets {
LiquidityNetData[] lower;
LiquidityNetData[] upper;
}
function getLiquidityNets(Uniswap3SC poolSC, TickRange memory tickRange, int24 tickSpacing, uint16 numTicks) internal view returns (LiquidityNets memory liquidityNets){
LiquidityNetData[] memory liquidityNetsUp = new LiquidityNetData[](numTicks);
LiquidityNetData[] memory liquidityNetsDown = new LiquidityNetData[](numTicks);
for (uint16 i = 0; i < numTicks; i++) {
int24 tickStep = (tickSpacing * int24(int16(i)));
//up
int24 tickUp = tickRange.upper + tickStep;
(, int128 lqNetUp, , , , , , ) = poolSC.ticks(tickUp);
liquidityNetsUp[i].tick = tickUp;
liquidityNetsUp[i].liquidityNet = lqNetUp;
//down
int24 tickDown = tickRange.lower - tickStep;
(, int128 lqNetDown, , , , , , ) = poolSC.ticks(tickDown);
liquidityNetsDown[i].tick = tickDown;
liquidityNetsDown[i].liquidityNet = lqNetDown;
}
liquidityNets.upper = liquidityNetsUp;
liquidityNets.lower = liquidityNetsDown;
}
function getCurrentTickData(address pool) external view returns (uint128 liquidity, int24 tick, int24 tickSpacing) {
Uniswap3SC poolSC = Uniswap3SC(pool);
liquidity = poolSC.liquidity();
(, tick, , , , , ) = poolSC.slot0();
tickSpacing = poolSC.tickSpacing();
}
function getTicksData(address pool, uint16 numTicks) external view returns (
uint128 liquidity,
int24 tick, int24 tickSpacing, int24[] memory tickRange,
LiquidityNetData[] memory liquidityNetsUpper, LiquidityNetData[] memory liquidityNetsLower,
address[] memory tokens
){
//create SC
Uniswap3SC poolSC = Uniswap3SC(pool);
//get liquidity, tick and tick space
liquidity = poolSC.liquidity();
(, tick, , , , , ) = poolSC.slot0();
tickSpacing = poolSC.tickSpacing();
//calculate the range for tick
TickRange memory tickRangeObj = calculateTickRange(tick, tickSpacing);
//put it in return variable
tickRange = new int24[](2);
tickRange[0] = tickRangeObj.lower;
tickRange[1] = tickRangeObj.upper;
//get liquidity nets for numTicks tickere
LiquidityNets memory liquidityNets = getLiquidityNets(poolSC, tickRangeObj, tickSpacing, numTicks);
//split them
liquidityNetsUpper = liquidityNets.upper;
liquidityNetsLower = liquidityNets.lower;
//get the tokens
tokens = new address[](2);
tokens[0] = poolSC.token0();
tokens[1] = poolSC.token1();
}
function getTickRange(int24 tick, int24 tickSpace) external pure returns (int24 lower, int24 upper) {
TickRange memory range = calculateTickRange(tick, tickSpace);
return (range.lower, range.upper);
}
}