uniswap / v3-subgraph Goto Github PK
View Code? Open in Web Editor NEWSubgraph for Uniswap V3
License: GNU General Public License v3.0
Subgraph for Uniswap V3
License: GNU General Public License v3.0
That query return an empty list for each entry burns, collects and mints:
query Events($owner: Bytes) {
burns(where: { owner: $owner }) {
owner
amount0
amount1
tickLower
tickUpper
}
collects(where: { owner: $owner }) {
id
owner
}
mints(where: { owner: $owner }) {
owner
amount0
amount1
tickLower
tickUpper
}
}
While this query:
positions(where: { owner: $owner }) {
id
liquidity
depositedToken0
depositedToken1
collectedFeesToken0
collectedFeesToken1
withdrawnToken0
withdrawnToken1
}
return a value for withdrawnToken and collectedFees.
So in all logic we should have something when querying the events burns, mints and collects by owner?
There is no data in the Collect entity when queried on thegraph.com.
There does not seem to be any references to Collect in the source code. Burn & Mint are being populated in core.ts, but nothing seems to be happening with Collect.
The collectedFeesToken0
and collectedFeesToken1
fields return 0 when fees were collected.
0xe168ca7482665665031a527e7fdcfabda163cf70f040c93ed9c6a58c4e1a49b1
Query
{
positionSnapshots(where:{transaction: "0xe168ca7482665665031a527e7fdcfabda163cf70f040c93ed9c6a58c4e1a49b1"}) {
collectedFeesToken0
collectedFeesToken1
}
}
Response
{
"data": {
"positionSnapshots": [
{
"collectedFeesToken0": "0",
"collectedFeesToken1": "0"
}
]
}
}
Seems like the types folder wasn't uploaded.
Uniswap graphQL via The Graph is a great way to provide Uniswap data without interacting directly with the contract (with Infura for instance).
For some data it's easily consumable without involving too much math. For instance you can get the token0price and token1price without calculating it from sqrtPrice.
But for other data, it's impossible to get what you want without being a math expert. Even if the equation seems easy like 6.3, 6.4, 6.5 and 6.6 in the whitepaper, it's fairly complex to implement due to the representation of numbers (big integer).
For instance would it be possible to have the feeGrowthInside0LastX128 for a position in a readable attribute in decimal.
Current output: 23943438193679638481270179092394037871828650
Actual output based on the UI: 3.99
How to calculate it? Math wizardry
I think raw data (sqrtPrice
, liquidity
, feeGrowthGlobal0X128
) should be available because it's "free" as stored in the blockchain. But it would be a huge improvement to have ready to consume data.
It would make one source of truth because by providing raw data, all consumers have to reimplement the calculation. It would also make possible to use the language of your choice. Today Uniswap libraries are only supported in Javascript/Typescript which makes sense but not always the best language depending on the use case.
What do you think?
Thanks
Why Uniswap graphs are not working?
https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2
Showing Error: Bad gateway
whats the uniswap-v3-subgraph office of arbitrum network?
"message": "No suitable indexer found for subgraph deployment"
I just noticed that there is a PR open to fix this - #16
Closing this issue.
Originally posted by @johnfriz in #25 (comment)
There's a transaction on Arbitrum (https://arbiscan.io/tx/0x1c295207effcdaa54baa7436068c57448ff8ace855b8d6f3f9c424b4b7603960) that throws the ETH/USDC pricing out of whack. This leads to a total fee number of 1701283934181940406345586170977804000000000000 USD 😂
These seem to be the options to fix the subgraph:
I'd like to query how much of the TVL is in active positions -- but I'm not sure that's available in the current subgraph.
For example, if the TVL is $4m, but 75% are out of range, the number I'd want to be able to query/determine is $1m -- the TVL isn't so useful for my purposes :D
I was working on a new app for Uniswap V3 when I discovered that most tokens do not return the correct value for derivedETH
in the V3 Subgraph. Seems like only the top 372 tokens return a non-zero value, even though it's relatively easy to calculate for quite a few others as well.
I tried to look at other issues and documentation and found no explanation or reason. Any insights on the issue?
It's not clear what exactly totalValueLockedToken0
and totalValueLockedToken1
are reflecting.
For instance, look at this UI screenshot:
The price of 0.9988 DAI per GUSD, and the liquidity distribution in the pool is such that 0.9988 is the upper bound of the liquidity range. If I'm not mistaken, this effectively means that all liquidity in the pool should have been converted to GUSD. Yet the Total Tokens Locked field shows 415.99 DAI (rather than 0.00 DAI) locked, and a subgraph query of totalValueLockedToken1
confirms this.
The total USD value of the tokens (roughly the sames totalValueLockedToken0 + totalValueLockedToken1
, as these are stablecoins) is also larger than the value obtained either by querying tick data or position data.
This particular pool was selected because it is very small and simple to analyze, but the same thing happens in other pools. The Total Tokens Locked are more than obtained by summing the ticks or by summing the open positions.
Even if we include uncollected fees in the amount (which I think the subgraph code does not do), the total value is still far too large.
Is this expected? If so, how to interpret the Total Tokens Locked values?
Hey,
I was facing this strange issue while querying the Graph on a recurring basis.
Just to confirm, are there any hard limits as to how many GraphQL queries can be performed per hour ?
Or any max query limits per month on The Graph
"Network error: unable to reach the Graph server"
reason: getaddrinfo ENOTFOUND api.thegraph.com
Thanks
Where can I find the code for these several subgraphs? For example, optimism-blocks, uniswap-optimism, arbitrum-one-blocks, uniswap-arbitrum-one
When I run
{
poolDayDatas(where: {pool: "0x99ac8ca7087fa4a2a1fb6357269965a2014abc35"}) {
open
close
}
}
the close price appears to be the same as the open price for all of the data. (The given pool address is just an example.) Is there a good reason for this to happen, or is it a bug?
As of last commit eef5b6e the Position entity is missing collectedToken0
and collectedToken1
fields
ERROR TS2339: Property 'collectedToken0' does not exist on type '~lib/@graphprotocol/graph-ts/index/TypedMap<~lib/string/String,~lib/@graphprotocol/graph-ts/index/Value>'.
position.collectedToken0 = position.collectedToken0.plus(amount0)
~~~~~~~~~~~~~~~
in src/mappings/position-manager.ts(171,11)
ERROR TS2339: Property 'collectedToken1' does not exist on type '~lib/@graphprotocol/graph-ts/index/TypedMap<~lib/string/String,~lib/@graphprotocol/graph-ts/index/Value>'.
position.collectedToken1 = position.collectedToken1.plus(amount1)
~~~~~~~~~~~~~~~
in src/mappings/position-manager.ts(172,11)
hello guys, in the v3 whitePaper we can see the tick's feeGrowthOutside{0,1}
that means when priceNow is bewteen tickLower and tickUpper.
feeGrowthInside{0,1} = feeGrowthGlobal{0,1} - tickLower.feeGrowthOutside{0,1} - tickUpper.feeGrowthOutside{0,1}. like
but when I query the subgrah return wrong answer.
{
ticks(where:{
pool_contains:"0x4e68ccd3e89f51c3074ca5072bbac773960dfa36"
tickIdx_in:[
-195660,
-195900]
}
block:{number:13010089}
)
{
tickIdx
feeGrowthOutside0X128
feeGrowthOutside1X128
pool
{
tick
feeGrowthGlobal0X128
feeGrowthGlobal1X128
}
}
}
{
"data": {
"ticks": [
{
"feeGrowthOutside0X128": "335883582520604181952009590658028448194028",
"feeGrowthOutside1X128": "854216468588660062387455627429334",
"pool": {
"feeGrowthGlobal0X128": "337450237140301366713991986895478281593300",
"feeGrowthGlobal1X128": "858801197364324603853037591152213",
"tick": "-195807"
},
"tickIdx": "-195660"
},
{
"feeGrowthOutside0X128": "281801500759483248405854115923760248801301",
"feeGrowthOutside1X128": "657493057862399273342033321023185",
"pool": {
"feeGrowthGlobal0X128": "337450237140301366713991986895478281593300",
"feeGrowthGlobal1X128": "858801197364324603853037591152213",
"tick": "-195807"
},
"tickIdx": "-195900"
}
]
}
}
as you see the current tick is -195807 and if I set the range in [-195900,-195660].
the feeInside0 = (feeGrowthGlobal0X128 - tickLower.feeGrowthOutside0X128 - tickUpper.feeGrowthOutside0X128)/(2^128);
but get feeInside0 = -823.53619 Less than 0.
is that have question?
https://thegraph.com/explorer/subgraph/uniswap/uniswap-v3
Position graphql type is available within code but unavailable on thegraph.
Anyone knows how to fix it?
Related to #73
Currently the subgraph does not work, checking the graph here:
We see the status:
Progress
97%
Current Block
#13606667
And the example query returns:
{
"errors": [
{
"message": "indexing_error"
}
]
}
Should we expect a fix anytime soon?
I've been trying out the following subgraphs:
https://thegraph.com/explorer/subgraph/ianlapham/uniswap-v3-subgraph
https://thegraph.com/explorer/subgraph/uniswap/uniswap-v3
The DayData endpoints give many orders of magnitude too big values. An example of too big USD values can be seen with the following query:
{
uniswapDayDatas {
id
date
tvlUSD
volumeUSD
}
}
The derivedETH for WBTC shows up as ~60. But WBTC to WETH is ~14.
Is there a definition of derivedETH
somewhere? I thought it was the ratio of one token to WETH.
Query:
query = """ query {
tokens(first: 200, orderBy: volumeUSD, orderDirection: desc){
id
symbol
name
derivedETH
}
}
"""
Table:
derivedETH id name symbol
0 1 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 Wrapped Ether WETH
1 0.0009321788898410236831507455122969672 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 USD Coin USDC
2 0.0009328062767106017689983160780445542 0xdac17f958d2ee523a2206206994597c13d831ec7 Tether USD USDT
3 0.0009320886134887074697753445864987579 0x6b175474e89094c44da98b954eedeac495271d0f Dai Stablecoin DAI
4 59.80635393663447363461328427003822 0x2260fac5e5542a773aa44fbcfedf7c193bc2c599 Wrapped BTC WBTC
pools(first:1 , orderBy:totalValueLockedUSD,orderDirection:desc)
{
totalValueLockedUSD
token1{
symbol
}
token0
{
symbol
}
id
ticks(first:5 , where:{tickIdx_gt:79000}, orderBy:tickIdx,orderDirection:asc)
{
tickIdx
}
}
It skips over tons of indexes around 79000, which is weird because the price of Ethereum is around 2696, 1.0001^79000 and on the analytics website, it displays lots of active liquidity in ticks 2700 to 1.0001^92040 range.
The results I get from this query on the graph protocol playground are below
"pools": [
{
"id": "0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8",
"ticks": [
{
"tickIdx": "92040"
},
{
"tickIdx": "92100"
},
{
"tickIdx": "105960"
},
{
"tickIdx": "115140"
},
{
"tickIdx": "120660"
}
],
"token0": {
"symbol": "USDC"
},
"token1": {
"symbol": "WETH"
},
"totalValueLockedUSD": "318379925.7999605472397433515988016"
}
I am trying to build this locally, but the files from src/types are missing. They seem to be getting deliberately excluded in the .gitignore file. What is the reason for this? Are community PRs not wanted for this project?
Conversion from here Uniswap/v3-info#186
pools
the TVL in terms of token0
and token1
is incorrectSteps to Reproduce (provided by @tcpzl)
Current Production State
Possible cause for error
Collect
events on pools correctly in this version of the subgraph. This means that as people collect fees - we dont subtract the collected amounst from the pool tvl. This would lead to the described issuesSolution*
amount0
and amount1
values and subtract them from the pool TVLThis issue is partially mentioned in #79
Pool and token volume return 0 even when the volume is clearly not 0.
Consider the query:
{
tokenHourDatas(first: 2, orderBy: periodStartUnix, orderDirection: desc) {
volumeUSD
}
}
It should return something like:
{
"data": {
"tokenHourDatas": [
{
"volumeUSD": "1.047233849876411772825075118826765"
},
{
"volumeUSD": "187.2817902553124062629485876002014"
}
]
}
}
See my polygon subgraph https://thegraph.com/hosted-service/subgraph/zephyrys/uniswap-polygon-but-it-works
But instead, it returns
{
"data": {
"tokenHourDatas": [
{
"volumeUSD": "0"
},
{
"volumeUSD": "0"
}
]
}
}
This issue is fully resolved by #93
I'm trying to get all the pools
created in Uniswap V3 using the method pools()
. Currently, the pools created are more than 1000 so I can't use the parameter first
to get them all (the limit is 1000).
I decided to use this approach:
pools
setting these parameters:pools(first: 1000, orderBy: createdAtTimestamp, orderDirection: asc) { id, createdAtBlockNumber, createdAtTimestamp }
pools
again setting these parameters:pools(first: 1000, orderBy: createdAtTimestamp, orderDirection: asc, where: {id_gt: "last_pool_address"}) { id, createdAtBlockNumber, createdAtTimestamp }
This step is a loop executed until the result has less than 1000 items.
The error here is I get the same pools twice, three times. Is there a way to get all the pools without having duplicates?
I could use the createdAtTimestamp_gt
parameter inside the where clause but it may happen I'll exclude pools created at the same timestamp.
Can we get an update with an ETA on when the issues will be fixed?
hello I want get each tick's volume locked in pool. such as USDC/ETH.
I have try to this:
fragment PoolFields on Pool {
id
txCount
sqrtPrice
token0
{
decimals
}
token1
{
decimals
}
ticks(first:5,where:{
pool:"0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8"
},orderBy:liquidityGross,orderDirection:desc){
tickIdx
liquidityGross
liquidityNet
price0
price1
}
token0Price
token1Price
liquidityProviderCount
} query {
pools(first: 1, orderBy: totalValueLockedUSD, orderDirection: desc, where: { volumeUSD_gt:0 }) {
...PoolFields
}
}
but the result haven't info .what API should I invoke? or convert liquidityGross liquidityNet?
hello. get the tick's feeGrowthOutside0X128 and feeGrowthOutside1X128 are difference with etherscan and subgraph.
here is the subgrah query;
{
ticks(where:{
pool_contains:"0x11b815efb8f581194ae79006d24e0d814b7697f6"
tickIdx:-195240
}
)
{
tickIdx
poolAddress
feeGrowthOutside0X128
feeGrowthOutside1X128
liquidityNet
liquidityGross
liquidityProviderCount
pool
{
feeGrowthGlobal0X128
feeGrowthGlobal1X128
tick
}
}
}
result is
{
"data": {
"ticks": [
{
"feeGrowthOutside0X128": "186457579433653700929913524141218714628394",
"feeGrowthOutside1X128": "459325821951671680232807424057021",
"liquidityGross": "22413817657280222",
"liquidityNet": "-22413817657280222",
"liquidityProviderCount": "0",
"pool": {
"feeGrowthGlobal0X128": "187786006713277915876322719076763842494893",
"feeGrowthGlobal1X128": "463522736213383582422368849416146",
"tick": "-195389"
},
"poolAddress": "0x11b815efb8f581194ae79006d24e0d814b7697f6",
"tickIdx": "-195240"
}
]
}
}
and this is the etherscan address:
https://etherscan.io/address/0x11b815efb8f581194ae79006d24e0d814b7697f6#readContract
and the result is :
Did a position for Eth/Sand on V3 but after that, it did everything in my metamask account but my postion is not appearing anywhere
The currently computed amountUSD of a swap is sometimes wrong, Sometimes the resulting output is 0, and sometimes it is divided by 2 when it shouldn't.
USD prices are computed in src/utils/pricing.ts this way:
let price0USD = token0.derivedETH.times(bundle.ethPriceUSD)
let price1USD = token1.derivedETH.times(bundle.ethPriceUSD)
When both tokens are whitelisted both amounts are supposed to be non-zero. However, sometimes the computed one of both outputs price{0-1}USD is 0, either because token0.derivedETH is 0 or bundle.ethPriceUSD is zero. ( I didn't find the root cause of the issue ).
In this case, when computing the amount USD price, when both tokens are whitelisted, you could avoid returning the wrong price in
// both are whitelist tokens, return sum of both amounts
if (WHITELIST_TOKENS.includes(token0.id) && WHITELIST_TOKENS.includes(token1.id)) {
return tokenAmount0.times(price0USD).plus(tokenAmount1.times(price1USD))
}
By first checking if one of both price{0-1}USD is 0. If this is the case you should return the non-zero prices multiplied by 2, instead of returning one of the two prices + 0. Otherwise, it will wrongly be divided by 2 when calling the function.
In the other cases when only one of both tokens is whitelisted sometimes a price of 0 is returned. I am not sure where this issue comes from ...
message: 'The
first argument must be between 0 and 1000, but is 10000'
It seems the Graph is limiting the number of all swaps to a cap of 1000.
Can this be overridden ? Or is there any alternate solution ?
When I query daily data, I get the correct fees/volume but hourly always returns 0. Here's an example but I looked at all active pools and every one showed the issue for me. Here is my query and response:
Am I doing something wrong or is this a bug? Or just misunderstanding and this is correct data?
These two fields of Position entity are missing in the schema.graphql file of main branch. However, it is used in position-manager.ts file
Please include these two entities there in main branch
collectedToken0: BigDecimal!
collectedToken1: BigDecimal!
Sorry, if this question is stupid, but should TotalValueLocked of some token to be equal or close to LP token balance?
14 177 942 blocks
Query:
pools(where: {id: "0x290a6a7460b308ee3f19023d2d00de604bcf5b42"}) {
id
txCount
token0 {
id
decimals
name
}
token1 {
id
decimals
name
}
totalValueLockedToken0
totalValueLockedToken1
}
}
Answer:
{
"data": {
"pools": [
{
"id": "0x290a6a7460b308ee3f19023d2d00de604bcf5b42",
"txCount": "85486",
"token0": {
"id": "0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0",
"decimals": "18",
"name": "Matic Token"
},
"token1": {
"id": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"decimals": "18",
"name": "Wrapped Ether"
},
"totalValueLockedToken0": "8423323.789566516739112524",
"totalValueLockedToken1": "4816.30806128660904193"
}
]
}
}
Token balance of pool (0x290a6a7460b308ee3f19023d2d00de604bcf5b42) at block 14177942:
matic: 6611283.796696814
weth: 3882.540883269949
Seems quite off. Is it error on my side, on the subgraph or both?
Hello, I fetch the token info with "whitelistPools"- the first pool's txCount >*2 of token txCount,
check the data below.
"token0": {
"id": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
"name": "Uniswap",
"symbol": "UNI",
"totalValueLockedUSD": "50006918.22001947589191434973769434",
"txCount": "2920",
"whitelistPools": [
{
"id": "0x1d42064fc4beb5f8aaf85f4617ae8b3b5b8bd801",
"token0": {
"symbol": "UNI"
},
"token1": {
"symbol": "WETH"
},
"txCount": "4240"
},
check it by simple query
query{
tokens(first:10 orderBy:txCount orderDirection:desc){
name
symbol
txCount
whitelistPools(first:1 orderDirection:desc orderBy:txCount){
token0{symbol}
token1{symbol}
id
txCount
}
}
}
UniswapV2 graph had the liquidityPosition
entity under a pool entity, so I could filter based on pool address and then get the LPs.
But in UniswapV3 graph, The Positions
Entity is on top level, So to get a particular pool's LPs I have to get all the LPs and then filter based on the pool address, It becomes computationally extensive as there are a large number of LPs and we can only get them in batches of 1000.
Is there a alternate route I am missing to get the LPs for a particular pool directly?
There isn't any documentation on this, but i'm assuming the collectedFeesTokenX = withdrawnTokenX + tokenXFees
It looks like since position id 138293, the collectedFeesToken
is either 0 or a completely wrong value.
{
positions(orderDirection:asc, first: 100, where:{ id_gt: 138200, liquidity: 0}){
id
liquidity
withdrawnToken0
withdrawnToken1
depositedToken0
depositedToken1
collectedFeesToken0
collectedFeesToken1
owner
token0{
symbol
}
token1{
symbol
}
transaction{
id
}
}
}
tokens
, which seems to be a max of 100 at the moment?Sharing a reference code:
https://replit.com/@10dimensions/HugeGratefulAdvance#index.js
Archive queries are currently very slow on Arbitrum, which means that the subgraph is currently indexing at a glacial pace.
The primary archive queries that are part of the subgraph are the total fee growth values (feeGrowthGlobal1X128). While this value is useful, I assume it's one of the least-accessed values in the subgraph. And if these values were removed from the graph, then most events could be indexed without archive queries and the graph should sync pretty quickly.
I have noticed that many of the token0Price and token1Price returned from the pools query are inaccurate.
I am calling the following query:
{
pools (first:1000,
orderBy:totalValueLockedETH,
orderDirection:desc) {
id
liquidity
totalValueLockedETH
totalValueLockedToken0
totalValueLockedToken1
token0Price
token0{
id
symbol
name
decimals
}
token1Price
token1{
id
symbol
name
decimals
}
}
}
One of the objects returned is:
{
"id": "0xc4002da5ceb8c65b3dd985f6c4a9bc961d932690",
"liquidity": "14676598827104346561852",
"totalValueLockedETH": "18.9421933297961722",
"totalValueLockedToken0": "18434587.88001087528047385",
"totalValueLockedToken1": "18.9421933297961722",
"token0Price": "1232236.224236843549578921623944695",
"token0": {
"id": "0x5d858bcd53e085920620549214a8b27ce2f04670",
"symbol": "POP",
"name": "POP Network Token",
"decimals": "18"
},
"token1Price": "0.0000008115327080400727716542071865924594",
"token1": {
"id": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"symbol": "WETH",
"name": "Wrapped Ether",
"decimals": "18"
}
}
However, on the Uniswap app, it gives a token0Price of 2296, and a token1Price of 0.000435459
This POP token is inactive, and this may contribute to it, however I have experienced the same thing with active tokens.
In this example, it is off by a factor of 10^4, but in general I am getting inaccuracies all over the place, up to a factor of 10^26. And in other cases where the result is within a power of 10, it is still not accurate to what I get when looking it up on the Uniswap app.
I want to know which range my position apply in an underlying pool, I get the tickLower and tickUpper returned by my position and try to look after them in the underlying pool, but they seems to be out of range.
Here is my query
positions(where: $where) {
id
owner
tickLower
tickUpper
pool {
ticks(orderBy: tickIdx) {
tickIdx
}
}
Here tickLower Idx do not exist in the list of ticks for the underlying pool, in my case the idX is too high... Is it an expected behaviour, how could that happen?
The subgraph is undocumented.
liquidity
value?volumeToken0
compare to totalValueLockedToken0
?volumeToken1
value negative? Is this related to #24 that has been merged 22 days ago?feesUSD
from? Does it account for all LPs?totalSupply
?untrackedVolumeUSD
?There are so many other questions for the above and all the other queries... I think this only makes sense to the folks that have built it or are intimately familiar with uniswap's codebase. Judging by the relevant channel in Uniswap's discord, these people are quite few and not answering questions.
Without documentation, there can be no adoption, this is not self-explanatory.
Please put the effort in to document the subgraph.
/cc @snreynolds
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.