Skip to content
Open
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
3 changes: 2 additions & 1 deletion Algebra/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ build/
node_modules/
src/types/
.DS_STORE
yarn-error.log
yarn-error.log
generated/
53 changes: 31 additions & 22 deletions Algebra/schema.graphql
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type Factory @entity {
type Factory @entity(immutable: false) {
# factory address
id: ID!
# amount of pools created
Expand Down Expand Up @@ -28,13 +28,13 @@ type Factory @entity {
}

# stores for USD calculations
type Bundle @entity {
type Bundle @entity(immutable: false) {
id: ID!
# price of Matic in usd
maticPriceUSD: BigDecimal!
}

type Token @entity {
type Token @entity(immutable: false) {
# token address
id: ID!
# token symbol
Expand Down Expand Up @@ -71,7 +71,7 @@ type Token @entity {
tokenDayData: [TokenDayData!]! @derivedFrom(field: "token")
}

type Pool @entity {
type Pool @entity(immutable: false) {
# pool address
id: ID!
# creation
Expand Down Expand Up @@ -148,7 +148,7 @@ type Pool @entity {
ticks: [Tick!]! @derivedFrom(field: "pool")
}

type Tick @entity {
type Tick @entity(immutable: false) {
# format: <pool address>#<tick index>
id: ID!
# pool address
Expand Down Expand Up @@ -194,7 +194,16 @@ type Tick @entity {
feeGrowthOutside1X128: BigInt!
}

type Position @entity {
type PoolPosition @entity(immutable: false) {
id: ID!
pool: Pool!
lowerTick: Tick!
upperTick: Tick!
owner: Bytes!
liquidity: BigInt!
}

type Position @entity(immutable: false) {
# Positions created through NonfungiblePositionManager
# NFT token id
id: ID!
Expand Down Expand Up @@ -238,7 +247,7 @@ type Position @entity {
token1Tvl : BigDecimal
}

type PositionSnapshot @entity {
type PositionSnapshot @entity(immutable: false) {
# <NFT token id>#<block number>
id: ID!
# owner of the NFT
Expand Down Expand Up @@ -272,7 +281,7 @@ type PositionSnapshot @entity {
feeGrowthInside1LastX128: BigInt!
}

type Transaction @entity {
type Transaction @entity(immutable: false) {
# txn hash
id: ID!
# block txn was included in
Expand All @@ -290,7 +299,7 @@ type Transaction @entity {
collects: [Collect!]! @derivedFrom(field: "transaction")
}

type Mint @entity {
type Mint @entity(immutable: false) {
# transaction hash + "#" + index in mints Transaction array
id: ID!
# which txn the mint was included in
Expand Down Expand Up @@ -325,7 +334,7 @@ type Mint @entity {
logIndex: BigInt
}

type Burn @entity {
type Burn @entity(immutable: false) {
# transaction hash + "#" + index in mints Transaction array
id: ID!
# txn burn was included in
Expand Down Expand Up @@ -358,7 +367,7 @@ type Burn @entity {
logIndex: BigInt
}

type Swap @entity {
type Swap @entity(immutable: false) {
# transaction hash + "#" + index in swaps Transaction array
id: ID!
# pointer to transaction
Expand Down Expand Up @@ -393,7 +402,7 @@ type Swap @entity {
logIndex: BigInt
}

type Collect @entity {
type Collect @entity(immutable: false) {
# transaction hash + "#" + index in collect Transaction array
id: ID!
# pointer to txn
Expand All @@ -418,7 +427,7 @@ type Collect @entity {
logIndex: BigInt
}

type Flash @entity {
type Flash @entity(immutable: false) {
# transaction hash + "-" + index in collect Transaction array
id: ID!
# pointer to txn
Expand Down Expand Up @@ -446,7 +455,7 @@ type Flash @entity {
}

# Data accumulated and condensed into day stats for all of Algebra
type AlgebraDayData @entity {
type AlgebraDayData @entity(immutable: false) {
# timestamp rounded to current day by dividing by 86400
id: ID!
# timestamp rounded to current day by dividing by 86400
Expand All @@ -466,7 +475,7 @@ type AlgebraDayData @entity {
}

# Data accumulated and condensed into day stats for each pool
type PoolDayData @entity {
type PoolDayData @entity(immutable: false) {
# timestamp rounded to current day by dividing by 86400
id: ID!
# timestamp rounded to current day by dividing by 86400
Expand Down Expand Up @@ -513,7 +522,7 @@ type PoolDayData @entity {
close: BigDecimal!
}

type PoolFeeData @entity{
type PoolFeeData @entity(immutable: false) {
id: ID!

pool: String
Expand All @@ -525,7 +534,7 @@ type PoolFeeData @entity{
}

# hourly stats tracker for pool
type PoolHourData @entity {
type PoolHourData @entity(immutable: false) {
# format: <pool address>-<timestamp>
id: ID!
# unix timestamp for start of hour
Expand Down Expand Up @@ -569,7 +578,7 @@ type PoolHourData @entity {
close: BigDecimal!
}

type TickHourData @entity {
type TickHourData @entity(immutable: false) {
# format: <pool address>-<tick index>-<timestamp>
id: ID!
# unix timestamp for start of hour
Expand All @@ -594,7 +603,7 @@ type TickHourData @entity {

# 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 {
type TickDayData @entity(immutable: false) {
# format: <pool address>-<tick index>-<timestamp>
id: ID!
# timestamp rounded to current day by dividing by 86400
Expand All @@ -620,7 +629,7 @@ type TickDayData @entity {
feeGrowthOutside1X128: BigInt!
}

type TokenDayData @entity {
type TokenDayData @entity(immutable: false) {
# token address concatendated with date
id: ID!
# timestamp rounded to current day by dividing by 86400
Expand Down Expand Up @@ -651,7 +660,7 @@ type TokenDayData @entity {
close: BigDecimal!
}

type TokenHourData @entity {
type TokenHourData @entity(immutable: false) {
# token address concatendated with date
id: ID!
# unix timestamp for start of hour
Expand Down Expand Up @@ -682,7 +691,7 @@ type TokenHourData @entity {
close: BigDecimal!
}

type FeeHourData @entity {
type FeeHourData @entity(immutable: false) {
#
id: ID!
#
Expand Down
63 changes: 30 additions & 33 deletions Algebra/src/mappings/core.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable prefer-const */
import { Bundle, Burn, Factory, Mint, Pool, Swap, Tick, Token,PoolFeeData } from '../types/schema'
import { Bundle, Burn, Factory, Mint, Pool, Swap, Tick, PoolPosition, Token,PoolFeeData } from '../types/schema'
import { Pool as PoolABI } from '../types/Factory/Pool'
import { BigDecimal, BigInt, ethereum, log} from '@graphprotocol/graph-ts'

Expand All @@ -13,7 +13,7 @@ import {
CommunityFee
} from '../types/templates/Pool/Pool'
import { convertTokenToDecimal, loadTransaction, safeDiv } from '../utils'
import { FACTORY_ADDRESS, ONE_BI, ZERO_BD, ZERO_BI, pools_list, TICK_SPACING } from '../utils/constants'
import { FACTORY_ADDRESS, ONE_BI, ZERO_BD, ZERO_BI, pools_list, TICK_SPACING, MAX_TVL } from '../utils/constants'
import { findEthPerToken, getEthPriceInUSD, getTrackedAmountUSD, priceToTokenPrices } from '../utils/pricing'
import {
updatePoolDayData,
Expand Down Expand Up @@ -107,6 +107,7 @@ export function handleMint(event: MintEvent): void {
pool.totalValueLockedMatic = pool.totalValueLockedToken0
.times(token0.derivedMatic)
.plus(pool.totalValueLockedToken1.times(token1.derivedMatic))
if (pool.totalValueLockedMatic > MAX_TVL) pool.totalValueLockedMatic = ZERO_BD
pool.totalValueLockedUSD = pool.totalValueLockedMatic.times(bundle.maticPriceUSD)

// reset aggregates with new amounts
Expand Down Expand Up @@ -154,6 +155,20 @@ export function handleMint(event: MintEvent): void {
upperTick.liquidityGross = upperTick.liquidityGross.plus(amount)
upperTick.liquidityNet = upperTick.liquidityNet.minus(amount)

let poolPositionid = pool.id + "#" + event.params.owner.toHexString() + '#' + BigInt.fromI32(event.params.bottomTick).toString() + "#" + BigInt.fromI32(event.params.topTick).toString()
let poolPosition = PoolPosition.load(poolPositionid)
if (poolPosition){
poolPosition.liquidity += event.params.liquidityAmount
}
else{
poolPosition = new PoolPosition(poolPositionid)
poolPosition.pool = pool.id
poolPosition.lowerTick = lowerTick.id
poolPosition.upperTick = upperTick.id
poolPosition.liquidity = event.params.liquidityAmount
poolPosition.owner = event.params.owner
}

// TODO: Update Tick's volume, fees, and liquidity provider count

updateAlgebraDayData(event)
Expand All @@ -167,6 +182,7 @@ export function handleMint(event: MintEvent): void {
token0.save()
token1.save()
pool.save()
poolPosition.save()
factory.save()
mint.save()

Expand All @@ -177,7 +193,6 @@ export function handleMint(event: MintEvent): void {
}

export function handleBurn(event: BurnEvent): void {

let bundle = Bundle.load('1')!
let poolAddress = event.address.toHexString()
let pool = Pool.load(poolAddress)!
Expand Down Expand Up @@ -233,6 +248,7 @@ export function handleBurn(event: BurnEvent): void {
pool.totalValueLockedMatic = pool.totalValueLockedToken0
.times(token0.derivedMatic)
.plus(pool.totalValueLockedToken1.times(token1.derivedMatic))
if (pool.totalValueLockedMatic > MAX_TVL) pool.totalValueLockedMatic = ZERO_BD
pool.totalValueLockedUSD = pool.totalValueLockedMatic.times(bundle.maticPriceUSD)

// reset aggregates with new amounts
Expand Down Expand Up @@ -268,6 +284,13 @@ export function handleBurn(event: BurnEvent): void {
upperTick.liquidityGross = upperTick.liquidityGross.minus(amount)
upperTick.liquidityNet = upperTick.liquidityNet.plus(amount)

let poolPositionid = pool.id + "#" + event.params.owner.toHexString() + '#' + BigInt.fromI32(event.params.bottomTick).toString() + "#" + BigInt.fromI32(event.params.topTick).toString()
let poolPosition = PoolPosition.load(poolPositionid)
if (poolPosition){
poolPosition.liquidity -= event.params.liquidityAmount
poolPosition.save()
}

updateAlgebraDayData(event)
updatePoolDayData(event)
updatePoolHourData(event)
Expand All @@ -286,6 +309,8 @@ export function handleBurn(event: BurnEvent): void {
}

export function handleSwap(event: SwapEvent): void {
if (event.block.number == BigInt.fromString("73551725"))
return
let bundle = Bundle.load('1')!
let factory = Factory.load(FACTORY_ADDRESS)!
let pool = Pool.load(event.address.toHexString())!
Expand Down Expand Up @@ -427,6 +452,7 @@ export function handleSwap(event: SwapEvent): void {
pool.totalValueLockedMatic = pool.totalValueLockedToken0
.times(token0.derivedMatic)
.plus(pool.totalValueLockedToken1.times(token1.derivedMatic))
if (pool.totalValueLockedMatic > MAX_TVL) pool.totalValueLockedMatic = ZERO_BD
pool.totalValueLockedUSD = pool.totalValueLockedMatic.times(bundle.maticPriceUSD)

factory.totalValueLockedMatic = factory.totalValueLockedMatic.plus(pool.totalValueLockedMatic)
Expand Down Expand Up @@ -536,29 +562,6 @@ export function handleSwap(event: SwapEvent): void {
// Current tick is initialized and needs to be updated
loadTickUpdateFeeVarsAndSave(newTick.toI32(), event)
}

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

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(TICK_SPACING.minus(modulo))
for (let i = firstInitialized; i.le(newTick); i = i.plus(TICK_SPACING)) {
loadTickUpdateFeeVarsAndSave(i.toI32(), event)
}
} else if (newTick.lt(oldTick)) {
let firstInitialized = oldTick.minus(modulo)
for (let i = firstInitialized; i.ge(newTick); i = i.minus(TICK_SPACING)) {
loadTickUpdateFeeVarsAndSave(i.toI32(), event)
}
}
}

export function handleSetCommunityFee(event: CommunityFee): void {
Expand Down Expand Up @@ -629,6 +632,7 @@ export function handleCollect(event: Collect): void {
pool.totalValueLockedMatic = pool.totalValueLockedToken0
.times(token0.derivedMatic)
.plus(pool.totalValueLockedToken1.times(token1.derivedMatic))
if (pool.totalValueLockedMatic > MAX_TVL) pool.totalValueLockedMatic = ZERO_BD
pool.totalValueLockedUSD = pool.totalValueLockedMatic.times(bundle.maticPriceUSD)

// reset aggregates with new amounts
Expand All @@ -644,13 +648,6 @@ export function handleCollect(event: Collect): void {


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)
}
Expand Down
3 changes: 2 additions & 1 deletion Algebra/src/mappings/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ export function handlePoolCreated(event: PoolEvent): void {
pool.feesToken0 = ZERO_BD
pool.feesToken1 = ZERO_BD
pool.untrackedVolumeUSD = ZERO_BD

pool.untrackedFeesUSD = ZERO_BD
pool.tick = ZERO_BI
pool.collectedFeesToken0 = ZERO_BD
pool.collectedFeesToken1 = ZERO_BD
pool.collectedFeesUSD = ZERO_BD
Expand Down
3 changes: 2 additions & 1 deletion Algebra/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import { Factory as FactoryContract } from '../types/templates/Pool/Factory'


export const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000'
export const FACTORY_ADDRESS = '0x9742E5C4452ccA62ce115d302756e9150CbA36Aa'
export const FACTORY_ADDRESS = '0x411b0fAcC3489691f28ad58c47006AF5E3Ab3A28'

export let ZERO_BI = BigInt.fromI32(0)
export let ONE_BI = BigInt.fromI32(1)
export let ZERO_BD = BigDecimal.fromString('0')
export let ONE_BD = BigDecimal.fromString('1')
export let BI_18 = BigInt.fromI32(18)
export let TICK_SPACING = BigInt.fromI32(60)
export let MAX_TVL = BigDecimal.fromString('500000000')

export let factoryContract = FactoryContract.bind(Address.fromString(FACTORY_ADDRESS))

Expand Down
Loading