Skip to content

Commit

Permalink
small updates for tracking swaps, pricing updates
Browse files Browse the repository at this point in the history
  • Loading branch information
ianlapham committed May 4, 2021
1 parent e926e13 commit d760666
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 29 deletions.
12 changes: 12 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ type Mint @entity {
timestamp: BigInt!
# pool position is within
pool: Pool!
# allow indexing by tokens
token0: Token!
# allow indexing by tokens
token1: Token!
# owner of position where liquidity minted to
owner: Bytes!
# the address that minted the liquidity
Expand Down Expand Up @@ -212,6 +216,10 @@ type Burn @entity {
transaction: Transaction!
# pool position is within
pool: Pool!
# allow indexing by tokens
token0: Token!
# allow indexing by tokens
token1: Token!
# need this to pull recent txns for specific token or pool
timestamp: BigInt!
# owner of position where liquidity was burned
Expand Down Expand Up @@ -243,6 +251,10 @@ type Swap @entity {
timestamp: BigInt!
# pool swap occured within
pool: Pool!
# allow indexing by tokens
token0: Token!
# allow indexing by tokens
token1: Token!
# sender of the swap
sender: Bytes!
# recipient of the swap
Expand Down
33 changes: 25 additions & 8 deletions src/mappings/core.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { log, Address } from '@graphprotocol/graph-ts'
/* eslint-disable prefer-const */
import { Bundle, Pool, Token, Factory, Mint, Burn, Swap, Tick } from '../types/schema'
import { BigDecimal, BigInt, store } from '@graphprotocol/graph-ts'
Expand All @@ -12,8 +13,12 @@ export function handleInitialize(event: Initialize): void {
let pool = Pool.load(event.address.toHexString())
pool.sqrtPrice = event.params.sqrtPriceX96
pool.tick = BigInt.fromI32(event.params.tick)
// update token prices
let token0 = Token.load(pool.token0)
let token1 = Token.load(pool.token1)

// token prices
let prices = sqrtPriceX96ToTokenPrices(pool.sqrtPrice)
let prices = sqrtPriceX96ToTokenPrices(pool.sqrtPrice, token0 as Token, token1 as Token)
pool.token0Price = prices[0]
pool.token1Price = prices[1]
pool.save()
Expand All @@ -26,8 +31,6 @@ export function handleInitialize(event: Initialize): void {
updatePoolDayData(event)

// update token prices
let token0 = Token.load(pool.token0)
let token1 = Token.load(pool.token1)
token0.derivedETH = findEthPerToken(token0 as Token)
token1.derivedETH = findEthPerToken(token1 as Token)
token0.save()
Expand All @@ -44,6 +47,10 @@ export function handleMint(event: MintEvent): void {
let token1 = Token.load(pool.token1)
let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals)
if (event.transaction.from === Address.fromString('0x74Aa01d162E6dC6A657caC857418C403D48E2D77')) {
log.debug('mybug token0 orice', [token0.derivedETH.toString()])
log.debug('mybug token1 orice', [token1.derivedETH.toString()])
}

let amountUSD = amount0
.times(token0.derivedETH.times(bundle.ethPriceUSD))
Expand Down Expand Up @@ -84,6 +91,8 @@ export function handleMint(event: MintEvent): void {
mint.transaction = transaction.id
mint.timestamp = transaction.timestamp
mint.pool = pool.id
mint.token0 = pool.token0
mint.token1 = pool.token1
mint.owner = event.params.owner
mint.sender = event.params.sender
mint.origin = event.transaction.from
Expand All @@ -101,10 +110,10 @@ export function handleMint(event: MintEvent): void {

let lowerTickId = poolAddress + '#' + BigInt.fromI32(event.params.tickLower).toString()
let upperTickId = poolAddress + '#' + BigInt.fromI32(event.params.tickUpper).toString()

let lowerTick = Tick.load(lowerTickId)
let upperTick = Tick.load(upperTickId)

if (lowerTick === null) {
lowerTick = createTick(lowerTickId, lowerTickIdx, pool.id, event)
}
Expand Down Expand Up @@ -187,6 +196,8 @@ export function handleBurn(event: BurnEvent): void {
burn.transaction = transaction.id
burn.timestamp = transaction.timestamp
burn.pool = pool.id
burn.token0 = pool.token0
burn.token1 = pool.token1
burn.owner = event.params.owner
burn.origin = event.transaction.from
burn.amount = event.params.amount
Expand Down Expand Up @@ -216,13 +227,13 @@ export function handleBurn(event: BurnEvent): void {
// If liquidity gross is zero then there are no positions starting at or ending at the tick.
// It is now safe to remove the tick from the data store.
if (lowerTick.liquidityGross.equals(ZERO_BD)) {
store.remove('Tick', lowerTickId);
store.remove('Tick', lowerTickId)
} else {
lowerTick.save()
}

if (upperTick.liquidityGross.equals(ZERO_BD)) {
store.remove('Tick', upperTickId);
store.remove('Tick', upperTickId)
} else {
upperTick.save()
}
Expand Down Expand Up @@ -266,6 +277,9 @@ export function handleSwap(event: SwapEvent): void {
let amountTotalETH = amount0ETH.plus(amount1ETH).div(BigDecimal.fromString('2'))
let amountTotalUSD = amount0USD.plus(amount1USD).div(BigDecimal.fromString('2'))

log.debug('mybug token0 Eth: {}', [token0.derivedETH.toString()])
log.debug('mybug token1 Eth: {}', [token1.derivedETH.toString()])

// global updates
factory.txCount = factory.txCount.plus(ONE_BI)
factory.totalVolumeETH = factory.totalVolumeETH.plus(amount0ETH).plus(amount1ETH)
Expand Down Expand Up @@ -300,7 +314,7 @@ export function handleSwap(event: SwapEvent): void {
token1.volumeUSD = token1.volumeUSD.plus(amountTotalUSD)

// updated pool rates
let prices = sqrtPriceX96ToTokenPrices(pool.sqrtPrice)
let prices = sqrtPriceX96ToTokenPrices(pool.sqrtPrice, token0 as Token, token1 as Token)
pool.token0Price = prices[0]
pool.token1Price = prices[1]
pool.save()
Expand Down Expand Up @@ -333,6 +347,8 @@ export function handleSwap(event: SwapEvent): void {
swap.transaction = transaction.id
swap.timestamp = transaction.timestamp
swap.pool = pool.id
swap.token0 = pool.token0
swap.token1 = pool.token1
swap.sender = event.params.sender
swap.origin = event.transaction.from
swap.recipient = event.params.recipient
Expand Down Expand Up @@ -365,6 +381,7 @@ export function handleSwap(event: SwapEvent): void {
token1DayData.volumeUSD = token1DayData.volumeUSD.plus(amountTotalUSD)
token1DayData.untrackedVolumeUSD = token1DayData.untrackedVolumeUSD.plus(amountTotalUSD)

swap.save()
token0DayData.save()
token1DayData.save()
uniswapDayData.save()
Expand Down
2 changes: 1 addition & 1 deletion src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { BigInt, BigDecimal, Address } from '@graphprotocol/graph-ts'
import { Factory as FactoryContract } from '../types/templates/Pool/Factory'

export const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000'
export const FACTORY_ADDRESS = '0xFeabCc62240297F1e4b238937D68e7516f0918D7'
export const FACTORY_ADDRESS = '0x815BCC87613315327E04e4A3b7c96a79Ae80760c'

export let ZERO_BI = BigInt.fromI32(0)
export let ONE_BI = BigInt.fromI32(1)
Expand Down
14 changes: 7 additions & 7 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@ export function exponentToBigDecimal(decimals: BigInt): BigDecimal {

export function bigDecimalExponated(value: BigDecimal, power: BigInt): BigDecimal {
if (power.equals(ZERO_BI)) {
return ONE_BD;
return ONE_BD
}
let negativePower = power.lt(ZERO_BI);
let result = ZERO_BD.plus(value);
let powerAbs = power.abs();
let negativePower = power.lt(ZERO_BI)
let result = ZERO_BD.plus(value)
let powerAbs = power.abs()
for (let i = ONE_BI; i.lt(powerAbs); i = i.plus(ONE_BI)) {
result = result.times(value)
}

if (negativePower) {
result = ONE_BD.div(result)
}
return result;

return result
}

export function tokenAmountToDecimal(tokenAmount: BigInt, exchangeDecimals: BigInt): BigDecimal {
Expand Down
43 changes: 32 additions & 11 deletions src/utils/pricing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@
import { ONE_BD, ZERO_BD } from './constants'
import { Pool, Token } from './../types/schema'
import { BigDecimal, BigInt } from '@graphprotocol/graph-ts'
import { exponentToBigDecimal } from '../utils/index'

let Q192 = 2 ** 192
export function sqrtPriceX96ToTokenPrices(sqrtPriceX96: BigInt): BigDecimal[] {
export function sqrtPriceX96ToTokenPrices(sqrtPriceX96: BigInt, token0: Token, token1: Token): BigDecimal[] {
let num = sqrtPriceX96.times(sqrtPriceX96).toBigDecimal()
let denom = BigDecimal.fromString(Q192.toString())
let price1 = num.div(denom)
let price1 = num
.div(denom)
.times(exponentToBigDecimal(token0.decimals))
.div(exponentToBigDecimal(token1.decimals))

let price0 = BigDecimal.fromString('1').div(price1)

return [price0, price1]
}

const WETH_ADDRESS = '0xc778417e063141139fce010982780140aa0cd5ab'
const DAI_WETH_03_POOL = '0x8ffb36fe19aaa22bf11f6a4f3dbcd4ae13842a67'
const DAI_WETH_03_POOL = '0x62fc2179597e23321cc2a77b1a77b72c98f5e1a5'

export function getEthPriceInUSD(): BigDecimal {
// fetch eth prices for each stablecoin
Expand All @@ -25,15 +31,14 @@ export function getEthPriceInUSD(): BigDecimal {
}
}

// token where amounts should contribute to tracked volume and liquidity
// let FEE_LEVELS_BIPS: number[] = [500, 3000, 10000]

// token where amounts should contribute to tracked volume and liquidity
export let WHITELIST_TOKENS: string[] = [
WETH_ADDRESS, // WETH
'0xc7ad46e0b8a400bb3c915120d284aafba8fc4735' // DAI
]

let MINIMUM_ETH_LOCKED = BigDecimal.fromString('1.5')

/**
* Search through graph to find derived Eth per token.
* @todo update to be derived ETH (add stablecoin estimates)
Expand All @@ -43,19 +48,35 @@ export function findEthPerToken(token: Token): BigDecimal {
return ONE_BD
}
let whiteList = token.whitelistPools
// for now just take USD from pool with greatest TVL
// need to update this to actually detect best rate based on liquidity distribution
let largestLiquidityETH = ZERO_BD
let priceSoFar = ZERO_BD

for (let i = 0; i < whiteList.length; ++i) {
let poolAddress = whiteList[i]
let pool = Pool.load(poolAddress)
if (pool.token0 == token.id) {
// whitelist token is token1
let token1 = Token.load(pool.token1)
// token1 per our token * Eth per token1
return pool.token1Price.times(token1.derivedETH as BigDecimal)
// get the derived ETH in pool
let ethLocked = pool.totalValueLockedToken1.times(token1.derivedETH)
if (ethLocked.gt(largestLiquidityETH) && ethLocked.gt(MINIMUM_ETH_LOCKED)) {
largestLiquidityETH = ethLocked
// token1 per our token * Eth per token1
priceSoFar = pool.token1Price.times(token1.derivedETH as BigDecimal)
}
}
if (pool.token1 == token.id) {
let token0 = Token.load(pool.token0)
// token0 per our token * ETH per token0
return pool.token0Price.times(token0.derivedETH as BigDecimal)
// get the derived ETH in pool
let ethLocked = pool.totalValueLockedToken0.times(token0.derivedETH)
if (ethLocked.gt(largestLiquidityETH) && ethLocked.gt(MINIMUM_ETH_LOCKED)) {
largestLiquidityETH = ethLocked
// token0 per our token * ETH per token0
priceSoFar = pool.token0Price.times(token0.derivedETH as BigDecimal)
}
}
}
return ZERO_BD // nothing was found return 0
return priceSoFar // nothing was found return 0
}
4 changes: 2 additions & 2 deletions subgraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ dataSources:
name: Factory
network: rinkeby
source:
address: '0xFeabCc62240297F1e4b238937D68e7516f0918D7'
address: '0x815BCC87613315327E04e4A3b7c96a79Ae80760c'
abi: Factory
startBlock: 8459128
startBlock: 8494387
mapping:
kind: ethereum/events
apiVersion: 0.0.3
Expand Down

0 comments on commit d760666

Please sign in to comment.