I am trying to compute tick liquidity for the ETH/USDC pair in Uniswap V3 within a range of +-10 tick spaces from the current tick. I'm querying pool and tick data using The Graph API. However, I've run into an issue: my computed liquidity for some ticks is negative, which contradicts my understanding that liquidity should always be positive.
Data Gathering
I initially query the pool data using the following GraphQL query:
pools(where: {or: [{id:"0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640"}]}) {
id
feeTier
sqrtPrice
tick
liquidity
token0 {
symbol
}
token1 {
symbol
}
}
Response:
{
id: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640',
feeTier: '500',
sqrtPrice: '1995791025043001032341104211323643',
tick: '202694',
liquidity: '23916677833605040001',
token0: { symbol: 'USDC' },
token1: { symbol: 'WETH' }
}
This provides me with a current tick of 202690 for the ETH/USDC pair.
Tick Data and Computation
Next, I query tick data within +-4 tick spaces from the current tick (202690) and attempt to compute liquidity.
{
ticks(where: {or: [{poolAddress:"0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",tickIdx_gte:202490,tickIdx_lte:202690}]}) {
id
poolAddress
tickIdx
liquidityGross
liquidityNet
}
}
[
{
id: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202650',
poolAddress: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640',
tickIdx: '202650',
liquidityGross: '2336388181864090595566',
liquidityNet: '492712989890016420068',
liquidity: 1441630710471656258600n
},
{
id: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202660',
poolAddress: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640',
tickIdx: '202660',
liquidityGross: '371131701748117601992',
liquidityNet: '-2458079249156612806780',
liquidity: -1016448538684956548180n
},
{
id: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202670',
poolAddress: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640',
tickIdx: '202670',
liquidityGross: '-1044298283082905453039',
liquidityNet: '1046161038635907397955',
liquidity: 29712499950950849775n
},
{
id: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202680',
poolAddress: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640',
tickIdx: '202680',
liquidityGross: '624539598789633437',
liquidityNet: '-624539598789633437',
liquidity: 29087960352161216338n
},
{
id: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202690',
poolAddress: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640',
tickIdx: '202690',
liquidityGross: '5171245502515484072',
liquidityNet: '-5171245502515484072',
liquidity: 23916714849645732266n
},
{
id: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202700',
poolAddress: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640',
tickIdx: '202700',
liquidityGross: '24478130685888414',
liquidityNet: '-15412937749140902',
liquidity: 23901301911896591364n
},
{
id: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202710',
poolAddress: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640',
tickIdx: '202710',
liquidityGross: '5028095487507403',
liquidityNet: '-5028095487507403',
liquidity: 23896273816409083961n
},
{
id: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202720',
poolAddress: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640',
tickIdx: '202720',
liquidityGross: '70992889483135757',
liquidityNet: '-70181736824935037',
liquidity: 23826092079584148924n
},
{
id: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202730',
poolAddress: '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640',
tickIdx: '202730',
liquidityGross: '2136174279021464652',
liquidityNet: '-1947978297530543726',
liquidity: 21878113782053605198n
}
]
I'm using the following formula to compute the liquidity for tick 202660:
tick[202660].liquidity = tick[262690].liquidity - tick[262690].liquidityNet - tick[262680].liquidityNet - tick[262670].liquidityNet
= -1016448538684956548180n
The result is a negative liquidity (-1016448538684956548180n), which seems incorrect.
Question
Is my computation for tick liquidity incorrect? If so, what is the correct way to calculate tick liquidity in Uniswap V3 for a given range?
========== 2023/09/27 updated ==========
I have compared the liquidityNet between ethscan and thegraphapi? The liquidityNet is difference in tick 202650~202670
thegraphapi
{
ticks(where: {or: [{poolAddress:"0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",tickIdx_gte:202600,tickIdx_lte:202700}]}) {
id
poolAddress
tickIdx
liquidityGross
liquidityNet
}
}
{
"data": {
"ticks": [
{
"id": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202600",
"poolAddress": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"tickIdx": "202600",
"liquidityGross": "1038000403835928850",
"liquidityNet": "-479724504561604558"
},
{
"id": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202610",
"poolAddress": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"tickIdx": "202610",
"liquidityGross": "8291996536383547138",
"liquidityNet": "-7176316981317573592"
},
{
"id": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202620",
"poolAddress": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"tickIdx": "202620",
"liquidityGross": "7956402413878331796",
"liquidityNet": "2279178812195187082"
},
{
"id": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202630",
"poolAddress": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"tickIdx": "202630",
"liquidityGross": "386008744872409375",
"liquidityNet": "310871568274768229"
},
{
"id": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202640",
"poolAddress": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"tickIdx": "202640",
"liquidityGross": "922181074779082625634",
"liquidityNet": "921376491976978808388"
},
{
"id": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202650",
"poolAddress": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"tickIdx": "202650",
"liquidityGross": "2341800287908032536731",
"liquidityNet": "487300883846074478903"
},
{
"id": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202660",
"poolAddress": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"tickIdx": "202660",
"liquidityGross": "371194532086084630838",
"liquidityNet": "-2458142079494579835626"
},
{
"id": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202670",
"poolAddress": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"tickIdx": "202670",
"liquidityGross": "-1045583905759190816622",
"liquidityNet": "1045587386689913628088"
},
{
"id": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202680",
"poolAddress": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"tickIdx": "202680",
"liquidityGross": "25806409821400891",
"liquidityNet": "-25806409821400891"
},
{
"id": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202690",
"poolAddress": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"tickIdx": "202690",
"liquidityGross": "4390795436492533285",
"liquidityNet": "-4235178605437148909"
},
{
"id": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#202700",
"poolAddress": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"tickIdx": "202700",
"liquidityGross": "583460706473303477",
"liquidityNet": "-574395513536555965"
}
ethscan
https://etherscan.io/address/0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640#readContract#F15
and input tick in ticks input box and then query
input 202650, get -378705826327612370
input 202660, get -2888234503751328
Is data of thegraphapi wrong?
liquidity
field in the v3-subgraphTick
entity, so curious how you're getting this.