Skip to content

Commit

Permalink
add price tracking token field
Browse files Browse the repository at this point in the history
  • Loading branch information
mzywang committed Apr 23, 2024
1 parent 9d8a918 commit ffe5618
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 55 deletions.
3 changes: 3 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ type Token @entity {
pairDayDataQuote: [PairDayData!]! @derivedFrom(field: "token1")
pairBase: [Pair!]! @derivedFrom(field: "token0")
pairQuote: [Pair!]! @derivedFrom(field: "token1")

# pairs used for USD pricing
priceTrackingPairs: [Pair!]!
}

type Pair @entity {
Expand Down
29 changes: 22 additions & 7 deletions src/mappings/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ export function handleTransfer(event: Transfer): void {
// this is to make sure all the mints are under the same transaction
if (mints.length === 0 || isCompleteMint(mints[mints.length - 1])) {
let mint = new MintEvent(
event.transaction.hash.toHexString().concat('-').concat(BigInt.fromI32(mints.length).toString()),
event.transaction.hash
.toHexString()
.concat('-')
.concat(BigInt.fromI32(mints.length).toString()),
)
mint.transaction = transaction.id
mint.pair = pair.id
Expand All @@ -92,7 +95,10 @@ export function handleTransfer(event: Transfer): void {
if (event.params.to.toHexString() == pair.id) {
let burns = transaction.burns
let burn = new BurnEvent(
event.transaction.hash.toHexString().concat('-').concat(BigInt.fromI32(burns.length).toString()),
event.transaction.hash
.toHexString()
.concat('-')
.concat(BigInt.fromI32(burns.length).toString()),
)
burn.transaction = transaction.id
burn.pair = pair.id
Expand Down Expand Up @@ -128,7 +134,10 @@ export function handleTransfer(event: Transfer): void {
burn = currentBurn as BurnEvent
} else {
burn = new BurnEvent(
event.transaction.hash.toHexString().concat('-').concat(BigInt.fromI32(burns.length).toString()),
event.transaction.hash
.toHexString()
.concat('-')
.concat(BigInt.fromI32(burns.length).toString()),
)
burn.transaction = transaction.id
burn.needsComplete = false
Expand All @@ -139,7 +148,10 @@ export function handleTransfer(event: Transfer): void {
}
} else {
burn = new BurnEvent(
event.transaction.hash.toHexString().concat('-').concat(BigInt.fromI32(burns.length).toString()),
event.transaction.hash
.toHexString()
.concat('-')
.concat(BigInt.fromI32(burns.length).toString()),
)
burn.transaction = transaction.id
burn.needsComplete = false
Expand Down Expand Up @@ -226,7 +238,7 @@ export function handleSync(event: Sync): void {
token0.save()
token1.save()

// get tracked liquidity - will be 0 if neither is in whitelist
// get tracked liquidity - will be 0 if neither is a price tracking token
let trackedLiquidityETH: BigDecimal
if (bundle.ethPrice.notEqual(ZERO_BD)) {
trackedLiquidityETH = getTrackedLiquidityUSD(pair.reserve0, token0 as Token, pair.reserve1, token1 as Token).div(
Expand Down Expand Up @@ -414,7 +426,7 @@ export function handleSwap(event: Swap): void {
.div(BigDecimal.fromString('2'))
let derivedAmountUSD = derivedAmountETH.times(bundle.ethPrice)

// only accounts for volume through white listed tokens
// only accounts for volume through price tracking tokens
let trackedAmountUSD = getTrackedVolumeUSD(amount0Total, token0 as Token, amount1Total, token1 as Token, pair as Pair)

let trackedAmountETH: BigDecimal
Expand Down Expand Up @@ -470,7 +482,10 @@ export function handleSwap(event: Swap): void {
}
let swaps = transaction.swaps
let swap = new SwapEvent(
event.transaction.hash.toHexString().concat('-').concat(BigInt.fromI32(swaps.length).toString()),
event.transaction.hash
.toHexString()
.concat('-')
.concat(BigInt.fromI32(swaps.length).toString()),
)

// update swap event
Expand Down
19 changes: 15 additions & 4 deletions src/mappings/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ZERO_BD,
ZERO_BI,
} from './helpers'
import { PRICE_TRACKING_TOKENS } from './pricing'

export function handleNewPair(event: PairCreated): void {
// load factory (create if first exchange)
Expand All @@ -35,7 +36,7 @@ export function handleNewPair(event: PairCreated): void {
factory.pairCount = factory.pairCount + 1
factory.save()

// create the tokens
let pair = new Pair(event.params.pair.toHexString()) as Pair
let token0 = Token.load(event.params.token0.toHexString())
let token1 = Token.load(event.params.token1.toHexString())

Expand All @@ -59,8 +60,8 @@ export function handleNewPair(event: PairCreated): void {
token0.tradeVolumeUSD = ZERO_BD
token0.untrackedVolumeUSD = ZERO_BD
token0.totalLiquidity = ZERO_BD
// token0.allPairs = []
token0.txCount = ZERO_BI
token0.priceTrackingPairs = []
}

// fetch info if null
Expand All @@ -81,11 +82,21 @@ export function handleNewPair(event: PairCreated): void {
token1.tradeVolumeUSD = ZERO_BD
token1.untrackedVolumeUSD = ZERO_BD
token1.totalLiquidity = ZERO_BD
// token1.allPairs = []
token1.txCount = ZERO_BI
token1.priceTrackingPairs = []
}

if (PRICE_TRACKING_TOKENS.includes(token0.id)) {
const priceTrackingPairs = token1.priceTrackingPairs
priceTrackingPairs.push(pair.id)
token1.priceTrackingPairs = priceTrackingPairs
}
if (PRICE_TRACKING_TOKENS.includes(token1.id)) {
const priceTrackingPairs = token0.priceTrackingPairs
priceTrackingPairs.push(pair.id)
token0.priceTrackingPairs = priceTrackingPairs
}

let pair = new Pair(event.params.pair.toHexString()) as Pair
pair.token0 = token0.id
pair.token1 = token1.id
pair.liquidityProviderCount = ZERO_BI
Expand Down
91 changes: 47 additions & 44 deletions src/mappings/pricing.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* eslint-disable prefer-const */
import { Address, BigDecimal, BigInt } from '@graphprotocol/graph-ts/index'
import { BigDecimal, BigInt } from '@graphprotocol/graph-ts/index'

import { Bundle, Pair, Token } from '../types/schema'
import { ADDRESS_ZERO, factoryContract, ONE_BD, UNTRACKED_PAIRS, ZERO_BD } from './helpers'
import { ONE_BD, UNTRACKED_PAIRS, ZERO_BD } from './helpers'

const WETH_ADDRESS = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'
const USDC_WETH_PAIR = '0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc' // created 10008355
Expand Down Expand Up @@ -40,7 +40,7 @@ export function getEthPriceInUSD(): BigDecimal {
}

// token where amounts should contribute to tracked volume and liquidity
let WHITELIST: string[] = [
export const PRICE_TRACKING_TOKENS: string[] = [
'0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // WETH
'0x6b175474e89094c44da98b954eedeac495271d0f', // DAI
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC
Expand Down Expand Up @@ -78,36 +78,36 @@ export function findEthPerToken(token: Token): BigDecimal {
if (token.id == WETH_ADDRESS) {
return ONE_BD
}
// loop through whitelist and check if paired with any
for (let i = 0; i < WHITELIST.length; ++i) {
let pairAddress = factoryContract.getPair(Address.fromString(token.id), Address.fromString(WHITELIST[i]))
if (pairAddress.toHexString() != ADDRESS_ZERO) {
let pair = Pair.load(pairAddress.toHexString())
if (pair === null) {
const priceTrackingPairs = token.priceTrackingPairs
for (let i = 0; i < priceTrackingPairs.length; i++) {
const pairAddress = priceTrackingPairs[i]
const pair = Pair.load(pairAddress)

if (pair === null) {
continue
}
if (pair.token0 == token.id && pair.reserveETH.gt(MINIMUM_LIQUIDITY_THRESHOLD_ETH)) {
let token1 = Token.load(pair.token1)
if (token1 === null) {
continue
}
if (pair.token0 == token.id && pair.reserveETH.gt(MINIMUM_LIQUIDITY_THRESHOLD_ETH)) {
let token1 = Token.load(pair.token1)
if (token1 === null) {
continue
}
return pair.token1Price.times(token1.derivedETH as BigDecimal) // return token1 per our token * Eth per token 1
}
if (pair.token1 == token.id && pair.reserveETH.gt(MINIMUM_LIQUIDITY_THRESHOLD_ETH)) {
let token0 = Token.load(pair.token0)
if (token0 === null) {
continue
}
return pair.token0Price.times(token0.derivedETH as BigDecimal) // return token0 per our token * ETH per token 0
return pair.token1Price.times(token1.derivedETH as BigDecimal) // return token1 per our token * Eth per token 1
}
if (pair.token1 == token.id && pair.reserveETH.gt(MINIMUM_LIQUIDITY_THRESHOLD_ETH)) {
let token0 = Token.load(pair.token0)
if (token0 === null) {
continue
}
return pair.token0Price.times(token0.derivedETH as BigDecimal) // return token0 per our token * ETH per token 0
}
}

return ZERO_BD // nothing was found return 0
}

/**
* Accepts tokens and amounts, return tracked amount based on token whitelist
* If one token on whitelist, return amount in that token converted to USD.
* Accepts tokens and amounts, return tracked amount based on price tracking tokens
* If one token is a price tracking token, return amount in that token converted to USD.
* If both are, return average of two amounts
* If neither is, return 0
*/
Expand All @@ -131,45 +131,48 @@ export function getTrackedVolumeUSD(
if (pair.liquidityProviderCount.lt(BigInt.fromI32(5))) {
let reserve0USD = pair.reserve0.times(price0)
let reserve1USD = pair.reserve1.times(price1)
if (WHITELIST.includes(token0.id) && WHITELIST.includes(token1.id)) {
if (PRICE_TRACKING_TOKENS.includes(token0.id) && PRICE_TRACKING_TOKENS.includes(token1.id)) {
if (reserve0USD.plus(reserve1USD).lt(MINIMUM_USD_THRESHOLD_NEW_PAIRS)) {
return ZERO_BD
}
}
if (WHITELIST.includes(token0.id) && !WHITELIST.includes(token1.id)) {
if (PRICE_TRACKING_TOKENS.includes(token0.id) && !PRICE_TRACKING_TOKENS.includes(token1.id)) {
if (reserve0USD.times(BigDecimal.fromString('2')).lt(MINIMUM_USD_THRESHOLD_NEW_PAIRS)) {
return ZERO_BD
}
}
if (!WHITELIST.includes(token0.id) && WHITELIST.includes(token1.id)) {
if (!PRICE_TRACKING_TOKENS.includes(token0.id) && PRICE_TRACKING_TOKENS.includes(token1.id)) {
if (reserve1USD.times(BigDecimal.fromString('2')).lt(MINIMUM_USD_THRESHOLD_NEW_PAIRS)) {
return ZERO_BD
}
}
}

// both are whitelist tokens, take average of both amounts
if (WHITELIST.includes(token0.id) && WHITELIST.includes(token1.id)) {
return tokenAmount0.times(price0).plus(tokenAmount1.times(price1)).div(BigDecimal.fromString('2'))
// both are price tracking tokens, take average of both amounts
if (PRICE_TRACKING_TOKENS.includes(token0.id) && PRICE_TRACKING_TOKENS.includes(token1.id)) {
return tokenAmount0
.times(price0)
.plus(tokenAmount1.times(price1))
.div(BigDecimal.fromString('2'))
}

// take full value of the whitelisted token amount
if (WHITELIST.includes(token0.id) && !WHITELIST.includes(token1.id)) {
// take full value of the price tracking token amount
if (PRICE_TRACKING_TOKENS.includes(token0.id) && !PRICE_TRACKING_TOKENS.includes(token1.id)) {
return tokenAmount0.times(price0)
}

// take full value of the whitelisted token amount
if (!WHITELIST.includes(token0.id) && WHITELIST.includes(token1.id)) {
// take full value of the price tracking token amount
if (!PRICE_TRACKING_TOKENS.includes(token0.id) && PRICE_TRACKING_TOKENS.includes(token1.id)) {
return tokenAmount1.times(price1)
}

// neither token is on white list, tracked volume is 0
// neither token is a price tracking token, tracked volume is 0
return ZERO_BD
}

/**
* Accepts tokens and amounts, return tracked amount based on token whitelist
* If one token on whitelist, return amount in that token converted to USD * 2.
* Accepts tokens and amounts, return tracked amount based on price tracking token list
* If one token is a price tracking token, return amount in that token converted to USD * 2.
* If both are, return sum of two amounts
* If neither is, return 0
*/
Expand All @@ -183,21 +186,21 @@ export function getTrackedLiquidityUSD(
let price0 = token0.derivedETH.times(bundle.ethPrice)
let price1 = token1.derivedETH.times(bundle.ethPrice)

// both are whitelist tokens, take average of both amounts
if (WHITELIST.includes(token0.id) && WHITELIST.includes(token1.id)) {
// both are price tracking tokens, take average of both amounts
if (PRICE_TRACKING_TOKENS.includes(token0.id) && PRICE_TRACKING_TOKENS.includes(token1.id)) {
return tokenAmount0.times(price0).plus(tokenAmount1.times(price1))
}

// take double value of the whitelisted token amount
if (WHITELIST.includes(token0.id) && !WHITELIST.includes(token1.id)) {
// take double value of the price tracking token amount
if (PRICE_TRACKING_TOKENS.includes(token0.id) && !PRICE_TRACKING_TOKENS.includes(token1.id)) {
return tokenAmount0.times(price0).times(BigDecimal.fromString('2'))
}

// take double value of the whitelisted token amount
if (!WHITELIST.includes(token0.id) && WHITELIST.includes(token1.id)) {
// take double value of the price tracking token amount
if (!PRICE_TRACKING_TOKENS.includes(token0.id) && PRICE_TRACKING_TOKENS.includes(token1.id)) {
return tokenAmount1.times(price1).times(BigDecimal.fromString('2'))
}

// neither token is on white list, tracked volume is 0
// neither token is a price tracking token, tracked volume is 0
return ZERO_BD
}

0 comments on commit ffe5618

Please sign in to comment.