Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove extra tick data, NFPM, and fee growth from subgraph #209

Merged
merged 6 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,193 changes: 0 additions & 1,193 deletions abis/NonfungiblePositionManager.json

This file was deleted.

2 changes: 1 addition & 1 deletion abis/pool.json
Original file line number Diff line number Diff line change
Expand Up @@ -985,4 +985,4 @@
"stateMutability": "view",
"type": "function"
}
]
]
157 changes: 0 additions & 157 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,6 @@ type Pool @entity {
liquidity: BigInt!
# current price tracker
sqrtPrice: BigInt!
# tracker for global fee growth
feeGrowthGlobal0X128: BigInt!
# tracker for global fee growth
feeGrowthGlobal1X128: BigInt!
# token0 per token1
token0Price: BigDecimal!
# token1 per token0
Expand Down Expand Up @@ -160,104 +156,10 @@ type Tick @entity {
price0: BigDecimal!
# calculated price of token1 of tick within this pool - constant
price1: BigDecimal!
# lifetime volume of token0 with this tick in range
volumeToken0: BigDecimal!
# lifetime volume of token1 with this tick in range
volumeToken1: BigDecimal!
# lifetime volume in derived USD with this tick in range
volumeUSD: BigDecimal!
# lifetime volume in untracked USD with this tick in range
untrackedVolumeUSD: BigDecimal!
# fees in USD
feesUSD: BigDecimal!
# all time collected fees in token0
collectedFeesToken0: BigDecimal!
# all time collected fees in token1
collectedFeesToken1: BigDecimal!
# all time collected fees in USD
collectedFeesUSD: BigDecimal!
# created time
createdAtTimestamp: BigInt!
# created block
createdAtBlockNumber: BigInt!
# Fields used to help derived relationship
liquidityProviderCount: BigInt! # used to detect new exchanges
# derived fields
# swaps: [Swap!]! @derivedFrom(field: "tick")
# vars needed for fee computation
feeGrowthOutside0X128: BigInt!
feeGrowthOutside1X128: BigInt!
}

type Position @entity {
# Positions created through NonfungiblePositionManager
# NFT token id
id: ID!
# owner of the NFT
owner: Bytes!
# pool position is within
pool: Pool!
# allow indexing by tokens
token0: Token!
# allow indexing by tokens
token1: Token!
# lower tick of the position
tickLower: Tick!
# upper tick of the position
tickUpper: Tick!
# total position liquidity
liquidity: BigInt!
# amount of token 0 ever deposited to position
depositedToken0: BigDecimal!
# amount of token 1 ever deposited to position
depositedToken1: BigDecimal!
# amount of token 0 ever withdrawn from position (without fees)
withdrawnToken0: BigDecimal!
# amount of token 1 ever withdrawn from position (without fees)
withdrawnToken1: BigDecimal!
# all time collected fees in token0
collectedFeesToken0: BigDecimal!
# all time collected fees in token1
collectedFeesToken1: BigDecimal!
# tx in which the position was initialized
transaction: Transaction!
# vars needed for fee computation
feeGrowthInside0LastX128: BigInt!
feeGrowthInside1LastX128: BigInt!
}

type PositionSnapshot @entity {
# <NFT token id>#<block number>
id: ID!
# owner of the NFT
owner: Bytes!
# pool the position is within
pool: Pool!
# position of which the snap was taken of
position: Position!
# block in which the snap was created
blockNumber: BigInt!
# timestamp of block in which the snap was created
timestamp: BigInt!
# total position liquidity
liquidity: BigInt!
# amount of token 0 ever deposited to position
depositedToken0: BigDecimal!
# amount of token 1 ever deposited to position
depositedToken1: BigDecimal!
# amount of token 0 ever withdrawn from position (without fees)
withdrawnToken0: BigDecimal!
# amount of token 1 ever withdrawn from position (without fees)
withdrawnToken1: BigDecimal!
# all time collected fees in token0
collectedFeesToken0: BigDecimal!
# all time collected fees in token1
collectedFeesToken1: BigDecimal!
# tx in which the snapshot was initialized
transaction: Transaction!
# internal vars needed for fee computation
feeGrowthInside0LastX128: BigInt!
feeGrowthInside1LastX128: BigInt!
}

type Transaction @entity {
Expand Down Expand Up @@ -469,10 +371,6 @@ type PoolDayData @entity {
token1Price: BigDecimal!
# current tick at end of period
tick: BigInt
# tracker for global fee growth
feeGrowthGlobal0X128: BigInt!
# tracker for global fee growth
feeGrowthGlobal1X128: BigInt!
# tvl derived in USD at end of period
tvlUSD: BigDecimal!
# volume in token0
Expand Down Expand Up @@ -513,10 +411,6 @@ type PoolHourData @entity {
token1Price: BigDecimal!
# current tick at end of period
tick: BigInt
# tracker for global fee growth
feeGrowthGlobal0X128: BigInt!
# tracker for global fee growth
feeGrowthGlobal1X128: BigInt!
# tvl derived in USD at end of period
tvlUSD: BigDecimal!
# volume in token0
Expand All @@ -539,57 +433,6 @@ type PoolHourData @entity {
close: BigDecimal!
}

type TickHourData @entity {
# format: <pool address>-<tick index>-<timestamp>
id: ID!
# unix timestamp for start of hour
periodStartUnix: Int!
# pointer to pool
pool: Pool!
# pointer to tick
tick: Tick!
# total liquidity pool has as tick lower or upper at end of period
liquidityGross: BigInt!
# how much liquidity changes when tick crossed at end of period
liquidityNet: BigInt!
# hourly volume of token0 with this tick in range
volumeToken0: BigDecimal!
# hourly volume of token1 with this tick in range
volumeToken1: BigDecimal!
# hourly volume in derived USD with this tick in range
volumeUSD: BigDecimal!
# fees in USD
feesUSD: BigDecimal!
}

# Data accumulated and condensed into day stats for each exchange
# Note: this entity gets saved only if there is a change during the day
type TickDayData @entity {
# format: <pool address>-<tick index>-<timestamp>
id: ID!
# timestamp rounded to current day by dividing by 86400
date: Int!
# pointer to pool
pool: Pool!
# pointer to tick
tick: Tick!
# total liquidity pool has as tick lower or upper at end of period
liquidityGross: BigInt!
# how much liquidity changes when tick crossed at end of period
liquidityNet: BigInt!
# hourly volume of token0 with this tick in range
volumeToken0: BigDecimal!
# hourly volume of token1 with this tick in range
volumeToken1: BigDecimal!
# hourly volume in derived USD with this tick in range
volumeUSD: BigDecimal!
# fees in USD
feesUSD: BigDecimal!
# vars needed for fee computation
feeGrowthOutside0X128: BigInt!
feeGrowthOutside1X128: BigInt!
}

type TokenDayData @entity {
# token address concatendated with date
id: ID!
Expand Down
89 changes: 5 additions & 84 deletions src/mappings/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { findEthPerToken, getEthPriceInUSD, getTrackedAmountUSD, sqrtPriceX96ToT
import {
updatePoolDayData,
updatePoolHourData,
updateTickDayData,
updateTokenDayData,
updateTokenHourData,
updateUniswapDayData
Expand Down Expand Up @@ -149,6 +148,9 @@ export function handleMint(event: MintEvent): void {
upperTick.liquidityGross = upperTick.liquidityGross.plus(amount)
upperTick.liquidityNet = upperTick.liquidityNet.minus(amount)

lowerTick.save()
upperTick.save()

// TODO: Update Tick's volume, fees, and liquidity provider count. Computing these on the tick
// level requires reimplementing some of the swapping code from v3-core.

Expand All @@ -165,10 +167,6 @@ export function handleMint(event: MintEvent): void {
pool.save()
factory.save()
mint.save()

// Update inner tick vars and save the ticks
updateTickFeeVarsAndSave(lowerTick, event)
updateTickFeeVarsAndSave(upperTick, event)
}
}

Expand Down Expand Up @@ -258,8 +256,8 @@ export function handleBurn(event: BurnEvent): void {
upperTick.liquidityGross = upperTick.liquidityGross.minus(amount)
upperTick.liquidityNet = upperTick.liquidityNet.plus(amount)

updateTickFeeVarsAndSave(lowerTick, event)
updateTickFeeVarsAndSave(upperTick, event)
lowerTick.save()
upperTick.save()
}
updateUniswapDayData(event)
updatePoolDayData(event)
Expand Down Expand Up @@ -409,13 +407,6 @@ export function handleSwap(event: SwapEvent): void {
swap.sqrtPriceX96 = event.params.sqrtPriceX96
swap.logIndex = event.logIndex

// update fee growth
let poolContract = PoolABI.bind(event.address)
let feeGrowthGlobal0X128 = poolContract.feeGrowthGlobal0X128()
let feeGrowthGlobal1X128 = poolContract.feeGrowthGlobal1X128()
pool.feeGrowthGlobal0X128 = feeGrowthGlobal0X128 as BigInt
pool.feeGrowthGlobal1X128 = feeGrowthGlobal1X128 as BigInt

// interval data
let uniswapDayData = updateUniswapDayData(event)
let poolDayData = updatePoolDayData(event)
Expand Down Expand Up @@ -473,75 +464,5 @@ export function handleSwap(event: SwapEvent): void {
pool.save()
token0.save()
token1.save()

// Update inner vars of current or crossed ticks
let newTick = pool.tick
if (oldTick && newTick) {
let tickSpacing = feeTierToTickSpacing(pool.feeTier)
let modulo = newTick.mod(tickSpacing)
if (modulo.equals(ZERO_BI)) {
// Current tick is initialized and needs to be updated
loadTickUpdateFeeVarsAndSave(newTick.toI32(), event)
}

let numIters = oldTick
.minus(newTick)
.abs()
.div(tickSpacing)

if (numIters.gt(BigInt.fromI32(100))) {
// In case more than 100 ticks need to be updated ignore the update in
// order to avoid timeouts. From testing this behavior occurs only upon
// pool initialization. This should not be a big issue as the ticks get
// updated later. For early users this error also disappears when calling
// collect
} else if (newTick.gt(oldTick)) {
let firstInitialized = oldTick.plus(tickSpacing.minus(modulo))
for (let i = firstInitialized; i.le(newTick); i = i.plus(tickSpacing)) {
loadTickUpdateFeeVarsAndSave(i.toI32(), event)
}
} else if (newTick.lt(oldTick)) {
let firstInitialized = oldTick.minus(modulo)
for (let i = firstInitialized; i.ge(newTick); i = i.minus(tickSpacing)) {
loadTickUpdateFeeVarsAndSave(i.toI32(), event)
}
}
}
}
}

export function handleFlash(event: FlashEvent): void {
mzywang marked this conversation as resolved.
Show resolved Hide resolved
// update fee growth
let pool = Pool.load(event.address.toHexString())!
let poolContract = PoolABI.bind(event.address)
let feeGrowthGlobal0X128 = poolContract.feeGrowthGlobal0X128()
let feeGrowthGlobal1X128 = poolContract.feeGrowthGlobal1X128()
pool.feeGrowthGlobal0X128 = feeGrowthGlobal0X128 as BigInt
pool.feeGrowthGlobal1X128 = feeGrowthGlobal1X128 as BigInt
pool.save()
}

function updateTickFeeVarsAndSave(tick: Tick, event: ethereum.Event): void {
let poolAddress = event.address
// not all ticks are initialized so obtaining null is expected behavior
let poolContract = PoolABI.bind(poolAddress)
let tickResult = poolContract.ticks(tick.tickIdx.toI32())
tick.feeGrowthOutside0X128 = tickResult.value2
tick.feeGrowthOutside1X128 = tickResult.value3
tick.save()

updateTickDayData(tick, event)
}

function loadTickUpdateFeeVarsAndSave(tickId: i32, event: ethereum.Event): void {
let poolAddress = event.address
let tick = Tick.load(
poolAddress
.toHexString()
.concat('#')
.concat(tickId.toString())
)
if (tick !== null) {
updateTickFeeVarsAndSave(tick, event)
}
}
2 changes: 0 additions & 2 deletions src/mappings/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ export function handlePoolCreated(event: PoolCreated): void {
pool.txCount = ZERO_BI
pool.liquidity = ZERO_BI
pool.sqrtPrice = ZERO_BI
pool.feeGrowthGlobal0X128 = ZERO_BI
pool.feeGrowthGlobal1X128 = ZERO_BI
pool.token0Price = ZERO_BD
pool.token1Price = ZERO_BD
pool.observationIndex = ZERO_BI
Expand Down
Loading
Loading