Skip to content

Commit

Permalink
add swaps, sync, and some optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
mzywang committed Dec 6, 2024
1 parent 0e6eca0 commit ce011ec
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 35 deletions.
26 changes: 25 additions & 1 deletion schema.graphql
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
type UniswapFactory @entity {
id: ID! # factory address, checksummed
pairCount: Int!
}

type Token @entity {
id: ID! # token address, lowercased
decimals: BigInt!

totalLiquidity: BigDecimal!

pairsAsToken0: [Pair!]! @derivedFrom(field: "token0")
pairsAsToken1: [Pair!]! @derivedFrom(field: "token1")
mintsAsToken0: [Mint!]! @derivedFrom(field: "token0")
mintsAsToken1: [Mint!]! @derivedFrom(field: "token1")
burnsAsToken0: [Burn!]! @derivedFrom(field: "token0")
burnsAsToken1: [Burn!]! @derivedFrom(field: "token1")
swapsAsToken0: [Swap!]! @derivedFrom(field: "token0")
swapsAsToken1: [Swap!]! @derivedFrom(field: "token1")
}

type Pair @entity {
Expand All @@ -20,7 +25,12 @@ type Pair @entity {
createdAtTimestamp: BigInt!
createdAtBlockNumber: BigInt!

reserve0: BigDecimal!
reserve1: BigDecimal!

mints: [Mint!]! @derivedFrom(field: "pair")
burns: [Burn!]! @derivedFrom(field: "pair")
swaps: [Swap!]! @derivedFrom(field: "pair")
}

type Mint @entity {
Expand Down Expand Up @@ -49,3 +59,17 @@ type Burn @entity {
to: Bytes!
}

type Swap @entity {
id: ID! # transactionhash#logIndex
timestamp: BigInt!
blockNumber: BigInt!
pair: Pair!
token0: Token!
token1: Token!
sender: Bytes!
amount0In: BigDecimal!
amount1In: BigDecimal!
amount0Out: BigDecimal!
amount1Out: BigDecimal!
to: Bytes!
}
47 changes: 22 additions & 25 deletions src/mappings/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,53 @@ import { log } from '@graphprotocol/graph-ts'
import { PairCreated } from '../types/Factory/Factory'
import { Pair, Token, UniswapFactory } from '../types/schema'
import { Pair as PairTemplate } from '../types/templates'
import { FACTORY_ADDRESS, fetchTokenDecimals, ZERO_BI } from './helpers'
import { FACTORY_ADDRESS, fetchTokenDecimals, ONE_BI, ZERO_BD } from './helpers'

export function handleNewPair(event: PairCreated): void {
let factory = UniswapFactory.load(FACTORY_ADDRESS)
// if it's the first pair, create the factory and the bundle
if (factory === null) {
factory = new UniswapFactory(FACTORY_ADDRESS)
factory.pairCount = 0
if (event.params.param3.equals(ONE_BI)) {
const factory = new UniswapFactory(FACTORY_ADDRESS)
factory.save()
}
factory.pairCount += 1
factory.save()

const pairAddress = event.params.pair.toHexString()

const token0Address = event.params.token0.toHexString()
let token0 = Token.load(token0Address)
if (token0 === null) {
token0 = new Token(token0Address)

if (Token.load(event.params.token0.toHexString()) === null) {
const decimals = fetchTokenDecimals(event.params.token0)
if (decimals === null) {
log.warning('Could not fetch decimals for token {}, skipping creation of pair {}.', [token0Address, pairAddress])
log.warning('Could not fetch decimals for token {}, skipping creation of pair {}.', [
event.params.token0.toHexString(),
event.params.pair.toHexString(),
])
return
}

const token0 = new Token(event.params.token0.toHexString())
token0.decimals = decimals
token0.totalLiquidity = ZERO_BD
token0.save()
}

const token1Address = event.params.token1.toHexString()
let token1 = Token.load(token1Address)
if (token1 === null) {
token1 = new Token(token1Address)

if (Token.load(event.params.token1.toHexString()) === null) {
const decimals = fetchTokenDecimals(event.params.token1)
if (decimals === null) {
log.warning('Could not fetch decimals for token {}, skipping creation of pair {}.', [token1Address, pairAddress])
log.warning('Could not fetch decimals for token {}, skipping creation of pair {}.', [
event.params.token1.toHexString(),
event.params.pair.toHexString(),
])
return
}

const token1 = new Token(event.params.token1.toHexString())
token1.decimals = decimals
token1.totalLiquidity = ZERO_BD
token1.save()
}

let pair = new Pair(pairAddress)
pair.token0 = token0.id
pair.token1 = token1.id
const pair = new Pair(event.params.pair.toHexString())
pair.token0 = event.params.token0.toHexString()
pair.token1 = event.params.token1.toHexString()
pair.createdAtTimestamp = event.block.timestamp
pair.createdAtBlockNumber = event.block.number
pair.reserve0 = ZERO_BD
pair.reserve1 = ZERO_BD
pair.save()

PairTemplate.create(event.params.pair)
Expand Down
10 changes: 4 additions & 6 deletions src/mappings/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable prefer-const */
import { Address, BigDecimal, BigInt } from '@graphprotocol/graph-ts'
import { Address, BigDecimal, BigInt, json } from '@graphprotocol/graph-ts'

import { ERC20 } from '../types/Factory/ERC20'

Expand All @@ -22,11 +22,9 @@ export function fetchTokenDecimals(tokenAddress: Address): BigInt | null {
}

export function exponentToBigDecimal(decimals: BigInt): BigDecimal {
let bd = ONE_BD
for (let i = ZERO_BI; i.lt(decimals as BigInt); i = i.plus(ONE_BI)) {
bd = bd.times(BigDecimal.fromString('10'))
}
return bd
const zeros = '0'.repeat(decimals.toI32())
const bigDecimalString = `1${zeros}`
return BigDecimal.fromString(bigDecimalString)
}

export function convertTokenToDecimal(tokenAmount: BigInt, exchangeDecimals: BigInt): BigDecimal {
Expand Down
48 changes: 45 additions & 3 deletions src/mappings/pair.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BigDecimal } from '@graphprotocol/graph-ts'
import { log } from '@graphprotocol/graph-ts'

import { Burn as BurnEntity, Mint as MintEntity, Pair, Token } from '../types/schema'
import { Burn as BurnEntity, Mint as MintEntity, Pair, Swap as SwapEntity, Token } from '../types/schema'
import { Burn, Mint, Swap, Sync } from '../types/templates/Pair/Pair'
import { convertTokenToDecimal } from './helpers'

Expand Down Expand Up @@ -63,9 +63,51 @@ export function handleBurn(event: Burn): void {
}

export function handleSwap(event: Swap): void {
log.info('Swap event received for pair {}.', [event.address.toHex()])
const block = event.block
const transaction = event.transaction
const swapId = transaction.hash.toHex() + '#' + event.logIndex.toString()

const pair = Pair.load(event.address.toHex())!
const token0 = Token.load(pair.token0)!
const token1 = Token.load(pair.token1)!

const token0AmountIn = convertTokenToDecimal(event.params.amount0In, token0.decimals)
const token1AmountIn = convertTokenToDecimal(event.params.amount1In, token1.decimals)
const token0AmountOut = convertTokenToDecimal(event.params.amount0Out, token0.decimals)
const token1AmountOut = convertTokenToDecimal(event.params.amount1Out, token1.decimals)

const swap = new SwapEntity(swapId)
swap.timestamp = block.timestamp
swap.blockNumber = block.number
swap.pair = pair.id
swap.token0 = token0.id
swap.token1 = token1.id
swap.sender = event.params.sender
swap.amount0In = token0AmountIn
swap.amount1In = token1AmountIn
swap.amount0Out = token0AmountOut
swap.amount1Out = token1AmountOut
swap.to = event.params.to
swap.save()
}

export function handleSync(event: Sync): void {
log.info('Sync event received for pair {}.', [event.address.toHex()])
const pair = Pair.load(event.address.toHex())!
const token0 = Token.load(pair.token0)!
const token1 = Token.load(pair.token1)!

const reserve0 = convertTokenToDecimal(event.params.reserve0, token0.decimals)
const reserve1 = convertTokenToDecimal(event.params.reserve1, token1.decimals)

const oldReserve0 = pair.reserve0
const oldReserve1 = pair.reserve1

pair.reserve0 = reserve0
pair.reserve1 = reserve1
pair.save()

token0.totalLiquidity = token0.totalLiquidity.plus(reserve0.minus(oldReserve0))
token1.totalLiquidity = token1.totalLiquidity.plus(reserve1.minus(oldReserve1))
token0.save()
token1.save()
}

0 comments on commit ce011ec

Please sign in to comment.