diff --git a/schema.graphql b/schema.graphql index 498b6a3f..bf6fd6ab 100644 --- a/schema.graphql +++ b/schema.graphql @@ -1,33 +1,41 @@ type UniswapFactory @entity { - # factory address - id: ID! + id: ID! # factory address, checksummed pairCount: Int! + txCount: BigInt! } type Token @entity { - # token address - id: ID! - + id: ID! # token address, lowercased decimals: BigInt! + txCount: BigInt! + + pairsAsToken0: [Pair!]! @derivedFrom(field: "token0") + pairsAsToken1: [Pair!]! @derivedFrom(field: "token1") + mintsAsToken0: [Mint!]! @derivedFrom(field: "token0") + mintsAsToken1: [Mint!]! @derivedFrom(field: "token1") } type Pair @entity { - # pair address - id: ID! - - # mirrored from the smart contract + id: ID! # pair address, lowercased token0: Token! token1: Token! - - # creation stats createdAtTimestamp: BigInt! createdAtBlockNumber: BigInt! + txCount: BigInt! + + mints: [Mint!]! @derivedFrom(field: "pair") } -# stores for USD calculations -type Bundle @entity { - # always 1 - id: ID! - ethPrice: BigDecimal! # price of ETH usd +type Mint @entity { + id: ID! # transactionhash#logIndex + timestamp: BigInt! + blockNumber: BigInt! + to: Bytes! + pair: Pair! + token0: Token! + token1: Token! + sender: Bytes! + amount0: BigDecimal! + amount1: BigDecimal! } diff --git a/src/mappings/factory.ts b/src/mappings/factory.ts index be98daf8..ed4f177c 100644 --- a/src/mappings/factory.ts +++ b/src/mappings/factory.ts @@ -1,9 +1,9 @@ /* eslint-disable prefer-const */ -import { Address, log } from '@graphprotocol/graph-ts' +import { log } from '@graphprotocol/graph-ts' import { PairCreated } from '../types/Factory/Factory' -import { Bundle, Pair, Token, UniswapFactory } from '../types/schema' -import { FACTORY_ADDRESS, fetchTokenDecimals, ZERO_BD } from './helpers' +import { Pair, Token, UniswapFactory } from '../types/schema' +import { FACTORY_ADDRESS, fetchTokenDecimals, ZERO_BI } from './helpers' export function handleNewPair(event: PairCreated): void { let factory = UniswapFactory.load(FACTORY_ADDRESS) @@ -11,12 +11,8 @@ export function handleNewPair(event: PairCreated): void { if (factory === null) { factory = new UniswapFactory(FACTORY_ADDRESS) factory.pairCount = 0 + factory.txCount = ZERO_BI factory.save() - - // create new bundle - let bundle = new Bundle('1') - bundle.ethPrice = ZERO_BD - bundle.save() } factory.pairCount += 1 factory.save() @@ -35,6 +31,7 @@ export function handleNewPair(event: PairCreated): void { } token0.decimals = decimals + token0.txCount = ZERO_BI token0.save() } @@ -50,6 +47,7 @@ export function handleNewPair(event: PairCreated): void { } token1.decimals = decimals + token1.txCount = ZERO_BI token1.save() } @@ -58,5 +56,6 @@ export function handleNewPair(event: PairCreated): void { pair.token1 = token1.id pair.createdAtTimestamp = event.block.timestamp pair.createdAtBlockNumber = event.block.number + pair.txCount = ZERO_BI pair.save() } diff --git a/src/mappings/helpers.ts b/src/mappings/helpers.ts index 499d13e2..9c096bd6 100644 --- a/src/mappings/helpers.ts +++ b/src/mappings/helpers.ts @@ -5,7 +5,10 @@ import { ERC20 } from '../types/Factory/ERC20' export const FACTORY_ADDRESS = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f' -export let ZERO_BD = BigDecimal.fromString('0') +export const ZERO_BD = BigDecimal.fromString('0') +export const ZERO_BI = BigInt.fromI32(0) +export const ONE_BD = BigDecimal.fromString('1') +export const ONE_BI = BigInt.fromI32(1) export function fetchTokenDecimals(tokenAddress: Address): BigInt | null { let contract = ERC20.bind(tokenAddress) @@ -17,3 +20,18 @@ export function fetchTokenDecimals(tokenAddress: Address): BigInt | null { } return 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 +} + +export function convertTokenToDecimal(tokenAmount: BigInt, exchangeDecimals: BigInt): BigDecimal { + if (exchangeDecimals == ZERO_BI) { + return tokenAmount.toBigDecimal() + } + return tokenAmount.toBigDecimal().div(exponentToBigDecimal(exchangeDecimals)) +} diff --git a/src/mappings/pair.ts b/src/mappings/pair.ts new file mode 100644 index 00000000..eb9daae9 --- /dev/null +++ b/src/mappings/pair.ts @@ -0,0 +1,49 @@ +import { BigDecimal } from '@graphprotocol/graph-ts' +import { log } from '@graphprotocol/graph-ts' + +import { Mint as MintEntity, Pair, Token, UniswapFactory } from '../types/schema' +import { Mint } from '../types/templates/Pair/Pair' +import { convertTokenToDecimal, FACTORY_ADDRESS, ONE_BI } from './helpers' + +export function handleMint(event: Mint): void { + const block = event.block + const transaction = event.transaction + const mintId = transaction.hash.toHex() + '#' + event.logIndex.toString() + + const transactionTo = transaction.to + + if (transactionTo === null) { + log.warning('Could not fetch transaction to address, skipping mint {}.', [mintId]) + return + } + + const uniswap = UniswapFactory.load(FACTORY_ADDRESS)! + const pair = Pair.load(event.address.toHex())! + const token0 = Token.load(pair.token0)! + const token1 = Token.load(pair.token1)! + + const token0Amount = convertTokenToDecimal(event.params.amount0, token0.decimals) + const token1Amount = convertTokenToDecimal(event.params.amount1, token1.decimals) + + token0.txCount = token0.txCount.plus(ONE_BI) + token1.txCount = token1.txCount.plus(ONE_BI) + pair.txCount = pair.txCount.plus(ONE_BI) + uniswap.txCount = uniswap.txCount.plus(ONE_BI) + + token0.save() + token1.save() + pair.save() + uniswap.save() + + const mint = new MintEntity(mintId) + mint.timestamp = block.timestamp + mint.blockNumber = block.number + mint.to = transactionTo + mint.pair = pair.id + mint.token0 = token0.id + mint.token1 = token1.id + mint.sender = event.params.sender + mint.amount0 = token0Amount as BigDecimal + mint.amount1 = token1Amount as BigDecimal + mint.save() +} diff --git a/subgraph.yaml b/subgraph.yaml index 526c3fa6..11fe7c11 100644 --- a/subgraph.yaml +++ b/subgraph.yaml @@ -30,4 +30,26 @@ dataSources: file: ./abis/ERC20NameBytes.json eventHandlers: - event: PairCreated(indexed address,indexed address,address,uint256) - handler: handleNewPair \ No newline at end of file + handler: handleNewPair +templates: + - kind: ethereum/contract + name: Pair + network: mainnet + source: + abi: Pair + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + file: ./src/mappings/pair.ts + entities: + - Pair + - Token + abis: + - name: Pair + file: ./abis/pair.json + - name: Factory + file: ./abis/factory.json + eventHandlers: + - event: Mint(indexed address,uint256,uint256) + handler: handleMint \ No newline at end of file