diff --git a/README.md b/README.md index e582d14f..f3460004 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Make sure to update package.json settings to point to your own graph account. ## Queries -Below are a few ways to show how to query the uniswap-subgraph for data. The queries show most of the information that is queryable, but there are many other filtering options that can be used, just check out the [querying api](https://thegraph.com/docs/graphql-api). These queries can be used locally or in The Graph Explorer playground. +Below are a few ways to show how to query the uniswap-subgraph for data. The queries show most of the information that is queryable, but there are many other filtering options that can be used, just check out the [querying api](https://thegraph.com/docs/en/subgraphs/querying/graphql-api/). These queries can be used locally or in The Graph Explorer playground. ## Key Entity Overviews diff --git a/package.json b/package.json index 407eaa84..5bf34d65 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ "watch-local": "graph deploy graphprotocol/Uniswap2 --watch --debug --node http://127.0.0.1:8020/ --ipfs http://localhost:5001" }, "devDependencies": { - "@graphprotocol/graph-cli": "^0.64.1", - "@graphprotocol/graph-ts": "^0.32.0", + "@graphprotocol/graph-cli": "^0.96.0", + "@graphprotocol/graph-ts": "^0.35.1", "@typescript-eslint/eslint-plugin": "^2.0.0", "@typescript-eslint/parser": "^2.0.0", "@uniswap/eslint-config": "^1.2.0", @@ -27,4 +27,4 @@ "prettier": "^1.18.2", "typescript": "^3.5.2" } -} +} \ No newline at end of file diff --git a/schema.graphql b/schema.graphql index 54f6dc4e..0b91386a 100644 --- a/schema.graphql +++ b/schema.graphql @@ -1,6 +1,6 @@ type UniswapFactory @entity { # factory address - id: ID! + id: Bytes! # pair info pairCount: Int! @@ -22,7 +22,7 @@ type UniswapFactory @entity { type Token @entity { # token address - id: ID! + id: Bytes! # mirrored from the smart contract symbol: String! @@ -56,7 +56,7 @@ type Token @entity { type Pair @entity { # pair address - id: ID! + id: Bytes! # mirrored from the smart contract token0: Token! @@ -96,12 +96,12 @@ type Pair @entity { } type User @entity { - id: ID! + id: Bytes! usdSwapped: BigDecimal! } -type Transaction @entity { - id: ID! # txn hash +type Transaction @entity(immutable: true) { + id: Bytes! # txn hash blockNumber: BigInt! timestamp: BigInt! # This is not the reverse of Mint.transaction; it is only used to @@ -111,9 +111,9 @@ type Transaction @entity { swaps: [Swap!]! } -type Mint @entity { - # transaction hash + "-" + index in mints Transaction array - id: ID! +type Mint @entity(immutable: true) { + # transaction hash + index in mints Transaction array + id: Bytes! transaction: Transaction! timestamp: BigInt! # need this to pull recent txns for specific token or pair pair: Pair! @@ -135,9 +135,9 @@ type Mint @entity { feeLiquidity: BigDecimal } -type Burn @entity { - # transaction hash + "-" + index in mints Transaction array - id: ID! +type Burn @entity(immutable: true) { + # transaction hash + index in mints Transaction array + id: Bytes! transaction: Transaction! timestamp: BigInt! # need this to pull recent txns for specific token or pair pair: Pair! @@ -162,9 +162,8 @@ type Burn @entity { feeLiquidity: BigDecimal } -type Swap @entity { - # transaction hash + "-" + index in swaps Transaction array - id: ID! +type Swap @entity(immutable: true) { + id: Bytes! transaction: Transaction! timestamp: BigInt! # need this to pull recent txns for specific token or pair pair: Pair! @@ -185,13 +184,13 @@ type Swap @entity { # stores for USD calculations type Bundle @entity { - id: ID! + id: Bytes! ethPrice: BigDecimal! # price of ETH usd } # Data accumulated and condensed into day stats for all of Uniswap type UniswapDayData @entity { - id: ID! # timestamp rounded to current day by dividing by 86400 + id: Bytes! # timestamp rounded to current day by dividing by 86400 date: Int! dailyVolumeETH: BigDecimal! @@ -207,7 +206,7 @@ type UniswapDayData @entity { } type PairHourData @entity { - id: ID! + id: Bytes! hourStartUnix: Int! # unix timestamp for start of hour pair: Pair! @@ -225,12 +224,12 @@ type PairHourData @entity { hourlyVolumeToken0: BigDecimal! hourlyVolumeToken1: BigDecimal! hourlyVolumeUSD: BigDecimal! - hourlyTxns: BigInt! + hourlyTxns: BigInt! } # Data accumulated and condensed into day stats for each exchange type PairDayData @entity { - id: ID! + id: Bytes! date: Int! pairAddress: Bytes! token0: Token! @@ -254,7 +253,7 @@ type PairDayData @entity { } type TokenDayData @entity { - id: ID! + id: Bytes! date: Int! token: Token! diff --git a/src/mappings/core.ts b/src/mappings/core.ts index 2862c3dc..bb71c12e 100644 --- a/src/mappings/core.ts +++ b/src/mappings/core.ts @@ -1,5 +1,5 @@ /* eslint-disable prefer-const */ -import { BigDecimal, BigInt, store } from '@graphprotocol/graph-ts' +import { BigDecimal, BigInt, Bytes, store } from '@graphprotocol/graph-ts' import { Bundle, @@ -16,18 +16,18 @@ import { updatePairDayData, updatePairHourData, updateTokenDayData, updateUniswa import { ADDRESS_ZERO, BI_18, convertTokenToDecimal, createUser, FACTORY_ADDRESS, ONE_BI, ZERO_BD } from './helpers' import { findEthPerToken, getEthPriceInUSD, getTrackedLiquidityUSD, getTrackedVolumeUSD } from './pricing' -function isCompleteMint(mintId: string): boolean { +function isCompleteMint(mintId: Bytes): boolean { return MintEvent.load(mintId)!.sender !== null // sufficient checks } export function handleTransfer(event: Transfer): void { // ignore initial transfers for first adds - if (event.params.to.toHexString() == ADDRESS_ZERO && event.params.value.equals(BigInt.fromI32(1000))) { + if (event.params.to == ADDRESS_ZERO && event.params.value.equals(BigInt.fromI32(1000))) { return } let factory = UniswapFactory.load(FACTORY_ADDRESS)! - let transactionHash = event.transaction.hash.toHexString() + let transactionHash = event.transaction.hash // user stats let from = event.params.from @@ -36,14 +36,14 @@ export function handleTransfer(event: Transfer): void { createUser(to) // get pair and load contract - let pair = Pair.load(event.address.toHexString())! + let pair = Pair.load(event.address)! // liquidity token amount being transfered let value = convertTokenToDecimal(event.params.value, BI_18) // get or create transaction let transaction = Transaction.load(transactionHash) - if (transaction === null) { + if (!transaction) { transaction = new Transaction(transactionHash) transaction.blockNumber = event.block.number transaction.timestamp = event.block.timestamp @@ -56,7 +56,7 @@ export function handleTransfer(event: Transfer): void { let mints = transaction.mints // part of the erc-20 standard (which is also the pool), whenever you mint new tokens, the from address is 0x0..0 // the pool is also the erc-20 that gets minted and transferred around - if (from.toHexString() == ADDRESS_ZERO) { + if (from == ADDRESS_ZERO) { // update total supply pair.totalSupply = pair.totalSupply.plus(value) pair.save() @@ -66,7 +66,7 @@ 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.concatI32(mints.length), ) mint.transaction = transaction.id mint.pair = pair.id @@ -89,10 +89,10 @@ export function handleTransfer(event: Transfer): void { // for every burn event, there is a transfer first from the LP to the pool (erc-20) // when you LP, you get an ERC-20 token which is the accounting token of the LP position // the thing that's actually getting transfered is the LP account token - if (event.params.to.toHexString() == pair.id) { + if (event.params.to == pair.id) { let burns = transaction.burns let burn = new BurnEvent( - event.transaction.hash.toHexString().concat('-').concat(BigInt.fromI32(burns.length).toString()), + event.transaction.hash.concatI32(burns.length), ) burn.transaction = transaction.id burn.pair = pair.id @@ -114,7 +114,7 @@ export function handleTransfer(event: Transfer): void { // burn // there's two transfers for the LP token, // first its going to move from the LP back to the pool, and then it will go from the pool to the zero address - if (event.params.to.toHexString() == ADDRESS_ZERO && event.params.from.toHexString() == pair.id) { + if (event.params.to == ADDRESS_ZERO && event.params.from == pair.id) { pair.totalSupply = pair.totalSupply.minus(value) pair.save() @@ -128,7 +128,7 @@ 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.concatI32(burns.length), ) burn.transaction = transaction.id burn.needsComplete = false @@ -139,7 +139,7 @@ export function handleTransfer(event: Transfer): void { } } else { burn = new BurnEvent( - event.transaction.hash.toHexString().concat('-').concat(BigInt.fromI32(burns.length).toString()), + event.transaction.hash.concatI32(burns.length), ) burn.transaction = transaction.id burn.needsComplete = false @@ -159,7 +159,7 @@ export function handleTransfer(event: Transfer): void { burn.feeTo = mint.to burn.feeLiquidity = mint.liquidity // remove the logical mint - store.remove('Mint', mints[mints.length - 1]) + store.remove('Mint', mints[mints.length - 1].toHexString()) // update the transaction // TODO: Consider using .slice().pop() to protect against unintended @@ -191,10 +191,10 @@ export function handleTransfer(event: Transfer): void { } export function handleSync(event: Sync): void { - let pair = Pair.load(event.address.toHex())! + let pair = Pair.load(event.address)! let token0 = Token.load(pair.token0) let token1 = Token.load(pair.token1) - if (token0 === null || token1 === null) { + if (!token0 || !token1) { return } let uniswap = UniswapFactory.load(FACTORY_ADDRESS)! @@ -217,7 +217,7 @@ export function handleSync(event: Sync): void { pair.save() // update ETH price now that reserves could have changed - let bundle = Bundle.load('1')! + let bundle = Bundle.load(Bytes.fromI32(1))! bundle.ethPrice = getEthPriceInUSD() bundle.save() @@ -261,24 +261,24 @@ export function handleSync(event: Sync): void { export function handleMint(event: Mint): void { // loaded from a previous handler creating this transaction // transfer event is emitted first and mint event is emitted afterwards, good to confirm with a protocol eng - let transaction = Transaction.load(event.transaction.hash.toHexString()) - if (transaction === null) { + let transaction = Transaction.load(event.transaction.hash) + if (!transaction) { return } let mints = transaction.mints let mint = MintEvent.load(mints[mints.length - 1]) - if (mint === null) { + if (!mint) { return } - let pair = Pair.load(event.address.toHex())! + let pair = Pair.load(event.address)! let uniswap = UniswapFactory.load(FACTORY_ADDRESS)! let token0 = Token.load(pair.token0) let token1 = Token.load(pair.token1) - if (token0 === null || token1 === null) { + if (!token0 || !token1) { return } @@ -291,7 +291,7 @@ export function handleMint(event: Mint): void { token1.txCount = token1.txCount.plus(ONE_BI) // get new amounts of USD and ETH for tracking - let bundle = Bundle.load('1')! + let bundle = Bundle.load(Bytes.fromI32(1))! let amountTotalUSD = token1.derivedETH .times(token1Amount) .plus(token0.derivedETH.times(token0Amount)) @@ -323,27 +323,27 @@ export function handleMint(event: Mint): void { } export function handleBurn(event: Burn): void { - let transaction = Transaction.load(event.transaction.hash.toHexString()) + let transaction = Transaction.load(event.transaction.hash) // safety check - if (transaction === null) { + if (!transaction) { return } let burns = transaction.burns let burn = BurnEvent.load(burns[burns.length - 1]) - if (burn === null) { + if (!burn) { return } - let pair = Pair.load(event.address.toHex())! + let pair = Pair.load(event.address)! let uniswap = UniswapFactory.load(FACTORY_ADDRESS)! //update token info let token0 = Token.load(pair.token0) let token1 = Token.load(pair.token1) - if (token0 === null || token1 === null) { + if (!token0 || !token1) { return } @@ -355,7 +355,7 @@ export function handleBurn(event: Burn): void { token1.txCount = token1.txCount.plus(ONE_BI) // get new amounts of USD and ETH for tracking - let bundle = Bundle.load('1')! + let bundle = Bundle.load(Bytes.fromI32(1))! let amountTotalUSD = token1.derivedETH .times(token1Amount) .plus(token0.derivedETH.times(token0Amount)) @@ -389,10 +389,10 @@ export function handleBurn(event: Burn): void { } export function handleSwap(event: Swap): void { - let pair = Pair.load(event.address.toHexString())! + let pair = Pair.load(event.address)! let token0 = Token.load(pair.token0) let token1 = Token.load(pair.token1) - if (token0 === null || token1 === null) { + if (!token0 || !token1) { return } let amount0In = convertTokenToDecimal(event.params.amount0In, token0.decimals) @@ -405,7 +405,7 @@ export function handleSwap(event: Swap): void { let amount1Total = amount1Out.plus(amount1In) // ETH/USD prices - let bundle = Bundle.load('1')! + let bundle = Bundle.load(Bytes.fromI32(1))! // get total amounts of derived USD and ETH for tracking let derivedAmountETH = token1.derivedETH @@ -459,9 +459,10 @@ export function handleSwap(event: Swap): void { token1.save() uniswap.save() - let transaction = Transaction.load(event.transaction.hash.toHexString()) - if (transaction === null) { - transaction = new Transaction(event.transaction.hash.toHexString()) + let txHash = event.transaction.hash + let transaction = Transaction.load(txHash) + if (!transaction) { + transaction = new Transaction(txHash) transaction.blockNumber = event.block.number transaction.timestamp = event.block.timestamp transaction.mints = [] @@ -469,9 +470,7 @@ export function handleSwap(event: Swap): void { transaction.burns = [] } let swaps = transaction.swaps - let swap = new SwapEvent( - event.transaction.hash.toHexString().concat('-').concat(BigInt.fromI32(swaps.length).toString()), - ) + let swap = new SwapEvent(txHash.concatI32(swaps.length)) // update swap event swap.transaction = transaction.id diff --git a/src/mappings/dayUpdates.ts b/src/mappings/dayUpdates.ts index 15326e9a..ea827fb9 100644 --- a/src/mappings/dayUpdates.ts +++ b/src/mappings/dayUpdates.ts @@ -1,5 +1,5 @@ /* eslint-disable prefer-const */ -import { BigDecimal, BigInt, ethereum } from '@graphprotocol/graph-ts' +import { BigDecimal, BigInt, Bytes, ethereum } from '@graphprotocol/graph-ts' import { Bundle, Pair, PairDayData, Token, TokenDayData, UniswapDayData, UniswapFactory } from '../types/schema' import { PairHourData } from './../types/schema' @@ -10,9 +10,9 @@ export function updateUniswapDayData(event: ethereum.Event): UniswapDayData { let timestamp = event.block.timestamp.toI32() let dayID = timestamp / 86400 let dayStartTimestamp = dayID * 86400 - let uniswapDayData = UniswapDayData.load(dayID.toString()) - if (uniswapDayData === null) { - uniswapDayData = new UniswapDayData(dayID.toString()) + let uniswapDayData = UniswapDayData.load(Bytes.fromI32(dayID)) + if (!uniswapDayData) { + uniswapDayData = new UniswapDayData(Bytes.fromI32(dayID)) uniswapDayData.date = dayStartTimestamp uniswapDayData.dailyVolumeUSD = ZERO_BD uniswapDayData.dailyVolumeETH = ZERO_BD @@ -33,10 +33,10 @@ export function updatePairDayData(event: ethereum.Event): PairDayData { let timestamp = event.block.timestamp.toI32() let dayID = timestamp / 86400 let dayStartTimestamp = dayID * 86400 - let dayPairID = event.address.toHexString().concat('-').concat(BigInt.fromI32(dayID).toString()) - let pair = Pair.load(event.address.toHexString())! + let dayPairID = event.address.concatI32(dayID) + let pair = Pair.load(event.address)! let pairDayData = PairDayData.load(dayPairID) - if (pairDayData === null) { + if (!pairDayData) { pairDayData = new PairDayData(dayPairID) pairDayData.date = dayStartTimestamp pairDayData.token0 = pair.token0 @@ -62,13 +62,13 @@ export function updatePairHourData(event: ethereum.Event): PairHourData { let timestamp = event.block.timestamp.toI32() let hourIndex = timestamp / 3600 // get unique hour within unix history let hourStartUnix = hourIndex * 3600 // want the rounded effect - let hourPairID = event.address.toHexString().concat('-').concat(BigInt.fromI32(hourIndex).toString()) - let pair = Pair.load(event.address.toHexString())! + let hourPairID = event.address.concatI32(hourIndex) + let pair = Pair.load(event.address)! let pairHourData = PairHourData.load(hourPairID) - if (pairHourData === null) { + if (!pairHourData) { pairHourData = new PairHourData(hourPairID) pairHourData.hourStartUnix = hourStartUnix - pairHourData.pair = event.address.toHexString() + pairHourData.pair = event.address pairHourData.hourlyVolumeToken0 = ZERO_BD pairHourData.hourlyVolumeToken1 = ZERO_BD pairHourData.hourlyVolumeUSD = ZERO_BD @@ -86,14 +86,14 @@ export function updatePairHourData(event: ethereum.Event): PairHourData { } export function updateTokenDayData(token: Token, event: ethereum.Event): TokenDayData { - let bundle = Bundle.load('1')! + let bundle = Bundle.load(Bytes.fromI32(1))! let timestamp = event.block.timestamp.toI32() let dayID = timestamp / 86400 let dayStartTimestamp = dayID * 86400 - let tokenDayID = token.id.toString().concat('-').concat(BigInt.fromI32(dayID).toString()) + let tokenDayID = token.id.concatI32(dayID) let tokenDayData = TokenDayData.load(tokenDayID) - if (tokenDayData === null) { + if (!tokenDayData) { tokenDayData = new TokenDayData(tokenDayID) tokenDayData.date = dayStartTimestamp tokenDayData.token = token.id diff --git a/src/mappings/factory.ts b/src/mappings/factory.ts index 0321a2e5..7ddb9fcc 100644 --- a/src/mappings/factory.ts +++ b/src/mappings/factory.ts @@ -1,5 +1,5 @@ /* eslint-disable prefer-const */ -import { log } from '@graphprotocol/graph-ts' +import { Bytes, log } from '@graphprotocol/graph-ts' import { PairCreated } from '../types/Factory/Factory' import { Bundle, Pair, Token, UniswapFactory } from '../types/schema' @@ -17,7 +17,7 @@ import { export function handleNewPair(event: PairCreated): void { // load factory (create if first exchange) let factory = UniswapFactory.load(FACTORY_ADDRESS) - if (factory === null) { + if (!factory) { factory = new UniswapFactory(FACTORY_ADDRESS) factory.pairCount = 0 factory.totalVolumeETH = ZERO_BD @@ -28,7 +28,7 @@ export function handleNewPair(event: PairCreated): void { factory.txCount = ZERO_BI // create new bundle - let bundle = new Bundle('1') + let bundle = new Bundle(Bytes.fromI32(1)) bundle.ethPrice = ZERO_BD bundle.save() } @@ -36,19 +36,19 @@ export function handleNewPair(event: PairCreated): void { factory.save() // create the tokens - let token0 = Token.load(event.params.token0.toHexString()) - let token1 = Token.load(event.params.token1.toHexString()) + let token0 = Token.load(event.params.token0) + let token1 = Token.load(event.params.token1) // fetch info if null - if (token0 === null) { - token0 = new Token(event.params.token0.toHexString()) + if (!token0) { + token0 = new Token(event.params.token0) token0.symbol = fetchTokenSymbol(event.params.token0) token0.name = fetchTokenName(event.params.token0) token0.totalSupply = fetchTokenTotalSupply(event.params.token0) let decimals = fetchTokenDecimals(event.params.token0) // bail if we couldn't figure out the decimals - if (decimals === null) { + if (!decimals) { log.debug('mybug the decimal on token 0 was null', []) return } @@ -64,15 +64,15 @@ export function handleNewPair(event: PairCreated): void { } // fetch info if null - if (token1 === null) { - token1 = new Token(event.params.token1.toHexString()) + if (!token1) { + token1 = new Token(event.params.token1) token1.symbol = fetchTokenSymbol(event.params.token1) token1.name = fetchTokenName(event.params.token1) token1.totalSupply = fetchTokenTotalSupply(event.params.token1) let decimals = fetchTokenDecimals(event.params.token1) // bail if we couldn't figure out the decimals - if (decimals === null) { + if (!decimals) { return } token1.decimals = decimals @@ -85,7 +85,7 @@ export function handleNewPair(event: PairCreated): void { token1.txCount = ZERO_BI } - let pair = new Pair(event.params.pair.toHexString()) as Pair + let pair = new Pair(event.params.pair) as Pair pair.token0 = token0.id pair.token1 = token1.id pair.liquidityProviderCount = ZERO_BI diff --git a/src/mappings/helpers.ts b/src/mappings/helpers.ts index adda9eb6..76156211 100644 --- a/src/mappings/helpers.ts +++ b/src/mappings/helpers.ts @@ -1,5 +1,5 @@ /* eslint-disable prefer-const */ -import { Address, BigDecimal, BigInt } from '@graphprotocol/graph-ts' +import { Address, BigDecimal, BigInt, Bytes } from '@graphprotocol/graph-ts' import { ERC20 } from '../types/Factory/ERC20' import { ERC20NameBytes } from '../types/Factory/ERC20NameBytes' @@ -8,8 +8,8 @@ import { User } from '../types/schema' import { Factory as FactoryContract } from '../types/templates/Pair/Factory' import { TokenDefinition } from './tokenDefinition' -export const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000' -export const FACTORY_ADDRESS = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f' +export const ADDRESS_ZERO = Address.fromString('0x0000000000000000000000000000000000000000') +export const FACTORY_ADDRESS = Address.fromString('0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f') export let ZERO_BI = BigInt.fromI32(0) export let ONE_BI = BigInt.fromI32(1) @@ -17,10 +17,10 @@ export let ZERO_BD = BigDecimal.fromString('0') export let ONE_BD = BigDecimal.fromString('1') export let BI_18 = BigInt.fromI32(18) -export let factoryContract = FactoryContract.bind(Address.fromString(FACTORY_ADDRESS)) +export let factoryContract = FactoryContract.bind(FACTORY_ADDRESS) // rebass tokens, dont count in tracked volume -export let UNTRACKED_PAIRS: string[] = ['0x9ea3b5b4ec044b70375236a281986106457b20ef'] +export let UNTRACKED_PAIRS: Bytes[] = [Bytes.fromHexString('0x9ea3b5b4ec044b70375236a281986106457b20ef')] export function exponentToBigDecimal(decimals: BigInt): BigDecimal { let bd = BigDecimal.fromString('1') @@ -61,8 +61,8 @@ export function isNullEthValue(value: string): boolean { export function fetchTokenSymbol(tokenAddress: Address): string { // static definitions overrides let staticDefinition = TokenDefinition.fromAddress(tokenAddress) - if (staticDefinition != null) { - return (staticDefinition as TokenDefinition).symbol + if (staticDefinition) { + return (staticDefinition).symbol } let contract = ERC20.bind(tokenAddress) @@ -89,8 +89,8 @@ export function fetchTokenSymbol(tokenAddress: Address): string { export function fetchTokenName(tokenAddress: Address): string { // static definitions overrides let staticDefinition = TokenDefinition.fromAddress(tokenAddress) - if (staticDefinition != null) { - return (staticDefinition as TokenDefinition).name + if (staticDefinition) { + return (staticDefinition).name } let contract = ERC20.bind(tokenAddress) @@ -116,10 +116,10 @@ export function fetchTokenName(tokenAddress: Address): string { // HOT FIX: we cant implement try catch for overflow catching so skip total supply parsing on these tokens that overflow // TODO: find better way to handle overflow -let SKIP_TOTAL_SUPPLY: string[] = ['0x0000000000bf2686748e1c0255036e7617e7e8a5'] +let SKIP_TOTAL_SUPPLY: Address[] = [Address.fromString('0x0000000000bf2686748e1c0255036e7617e7e8a5')] export function fetchTokenTotalSupply(tokenAddress: Address): BigInt { - if (SKIP_TOTAL_SUPPLY.includes(tokenAddress.toHexString())) { + if (SKIP_TOTAL_SUPPLY.includes(tokenAddress)) { return BigInt.fromI32(0) } const contract = ERC20.bind(tokenAddress) @@ -134,8 +134,8 @@ export function fetchTokenTotalSupply(tokenAddress: Address): BigInt { export function fetchTokenDecimals(tokenAddress: Address): BigInt | null { // static definitions overrides let staticDefinition = TokenDefinition.fromAddress(tokenAddress) - if (staticDefinition != null) { - return (staticDefinition as TokenDefinition).decimals + if (staticDefinition) { + return (staticDefinition).decimals } let contract = ERC20.bind(tokenAddress) @@ -149,9 +149,9 @@ export function fetchTokenDecimals(tokenAddress: Address): BigInt | null { } export function createUser(address: Address): void { - let user = User.load(address.toHexString()) - if (user === null) { - user = new User(address.toHexString()) + let user = User.load(address) + if (!user) { + user = new User(address) user.usdSwapped = ZERO_BD user.save() } diff --git a/src/mappings/pricing.ts b/src/mappings/pricing.ts index c49b32f8..cc2db215 100644 --- a/src/mappings/pricing.ts +++ b/src/mappings/pricing.ts @@ -1,13 +1,13 @@ /* eslint-disable prefer-const */ -import { Address, BigDecimal, BigInt } from '@graphprotocol/graph-ts/index' +import { Bytes, BigDecimal, BigInt, Address, } from '@graphprotocol/graph-ts' import { Bundle, Pair, Token } from '../types/schema' import { ADDRESS_ZERO, factoryContract, ONE_BD, UNTRACKED_PAIRS, ZERO_BD } from './helpers' -const WETH_ADDRESS = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' -const USDC_WETH_PAIR = '0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc' // created 10008355 -const DAI_WETH_PAIR = '0xa478c2975ab1ea89e8196811f51a7b7ade33eb11' // created block 10042267 -const USDT_WETH_PAIR = '0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852' // created block 10093341 +const WETH_Bytes = Bytes.fromHexString('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') +const USDC_WETH_PAIR = Bytes.fromHexString('0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc') // created 10008355 +const DAI_WETH_PAIR = Bytes.fromHexString('0xa478c2975ab1ea89e8196811f51a7b7ade33eb11') // created block 10042267 +const USDT_WETH_PAIR = Bytes.fromHexString('0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852') // created block 10093341 export function getEthPriceInUSD(): BigDecimal { // fetch eth prices for each stablecoin @@ -16,7 +16,7 @@ export function getEthPriceInUSD(): BigDecimal { let usdtPair = Pair.load(USDT_WETH_PAIR) // usdt is token1 // all 3 have been created - if (daiPair !== null && usdcPair !== null && usdtPair !== null) { + if (daiPair && usdcPair && usdtPair) { let totalLiquidityETH = daiPair.reserve1.plus(usdcPair.reserve1).plus(usdtPair.reserve0) let daiWeight = daiPair.reserve1.div(totalLiquidityETH) let usdcWeight = usdcPair.reserve1.div(totalLiquidityETH) @@ -26,13 +26,13 @@ export function getEthPriceInUSD(): BigDecimal { .plus(usdcPair.token0Price.times(usdcWeight)) .plus(usdtPair.token1Price.times(usdtWeight)) // dai and USDC have been created - } else if (daiPair !== null && usdcPair !== null) { + } else if (daiPair && usdcPair) { let totalLiquidityETH = daiPair.reserve1.plus(usdcPair.reserve1) let daiWeight = daiPair.reserve1.div(totalLiquidityETH) let usdcWeight = usdcPair.reserve1.div(totalLiquidityETH) return daiPair.token0Price.times(daiWeight).plus(usdcPair.token0Price.times(usdcWeight)) // USDC is the only pair so far - } else if (usdcPair !== null) { + } else if (usdcPair) { return usdcPair.token0Price } else { return ZERO_BD @@ -40,28 +40,28 @@ export function getEthPriceInUSD(): BigDecimal { } // token where amounts should contribute to tracked volume and liquidity -let WHITELIST: string[] = [ - '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // WETH - '0x6b175474e89094c44da98b954eedeac495271d0f', // DAI - '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC - '0xdac17f958d2ee523a2206206994597c13d831ec7', // USDT - '0x0000000000085d4780b73119b644ae5ecd22b376', // TUSD - '0x5d3a536e4d6dbd6114cc1ead35777bab948e3643', // cDAI - '0x39aa39c021dfbae8fac545936693ac917d5e7563', // cUSDC - '0x86fadb80d8d2cff3c3680819e4da99c10232ba0f', // EBASE - '0x57ab1ec28d129707052df4df418d58a2d46d5f51', // sUSD - '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2', // MKR - '0xc00e94cb662c3520282e6f5717214004a7f26888', // COMP - '0x514910771af9ca656af840dff83e8264ecf986ca', //LINK - '0x960b236a07cf122663c4303350609a66a7b288c0', //ANT - '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f', //SNX - '0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e', //YFI - '0xdf5e0e81dff6faf3a7e52ba697820c5e32d806a8', // yCurv - '0x853d955acef822db058eb8505911ed77f175b99e', // FRAX - '0xa47c8bf37f92abed4a126bda807a7b7498661acd', // WUST - '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984', // UNI - '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', // WBTC - '0x956f47f50a910163d8bf957cf5846d573e7f87ca', // FEI +let WHITELIST: Bytes[] = [ + Bytes.fromHexString('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'), // WETH + Bytes.fromHexString('0x6b175474e89094c44da98b954eedeac495271d0f'), // DAI + Bytes.fromHexString('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'), // USDC + Bytes.fromHexString('0xdac17f958d2ee523a2206206994597c13d831ec7'), // USDT + Bytes.fromHexString('0x0000000000085d4780b73119b644ae5ecd22b376'), // TUSD + Bytes.fromHexString('0x5d3a536e4d6dbd6114cc1ead35777bab948e3643'), // cDAI + Bytes.fromHexString('0x39aa39c021dfbae8fac545936693ac917d5e7563'), // cUSDC + Bytes.fromHexString('0x86fadb80d8d2cff3c3680819e4da99c10232ba0f'), // EBASE + Bytes.fromHexString('0x57ab1ec28d129707052df4df418d58a2d46d5f51'), // sUSD + Bytes.fromHexString('0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2'), // MKR + Bytes.fromHexString('0xc00e94cb662c3520282e6f5717214004a7f26888'), // COMP + Bytes.fromHexString('0x514910771af9ca656af840dff83e8264ecf986ca'), // LINK + Bytes.fromHexString('0x960b236a07cf122663c4303350609a66a7b288c0'), // ANT + Bytes.fromHexString('0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f'), // SNX + Bytes.fromHexString('0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e'), // YFI + Bytes.fromHexString('0xdf5e0e81dff6faf3a7e52ba697820c5e32d806a8'), // yCurv + Bytes.fromHexString('0x853d955acef822db058eb8505911ed77f175b99e'), // FRAX + Bytes.fromHexString('0xa47c8bf37f92abed4a126bda807a7b7498661acd'), // WUST + Bytes.fromHexString('0x1f9840a85d5af5bf1d1762f925bdaddc4201f984'), // UNI + Bytes.fromHexString('0x2260fac5e5542a773aa44fbcfedf7c193bc2c599'), // WBTC + Bytes.fromHexString('0x956f47f50a910163d8bf957cf5846d573e7f87ca'), // FEI ] // minimum liquidity required to count towards tracked volume for pairs with small # of Lps @@ -75,27 +75,27 @@ let MINIMUM_LIQUIDITY_THRESHOLD_ETH = BigDecimal.fromString('2') * @todo update to be derived ETH (add stablecoin estimates) **/ export function findEthPerToken(token: Token): BigDecimal { - if (token.id == WETH_ADDRESS) { + if (token.id == WETH_Bytes) { 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) { + let pairBytes = factoryContract.getPair(Address.fromBytes(token.id), Address.fromBytes(WHITELIST[i])) + if (pairBytes != ADDRESS_ZERO) { + let pair = Pair.load(pairBytes) + if (!pair) { continue } if (pair.token0 == token.id && pair.reserveETH.gt(MINIMUM_LIQUIDITY_THRESHOLD_ETH)) { let token1 = Token.load(pair.token1) - if (token1 === null) { + if (!token1) { 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) { + if (!token0) { continue } return pair.token0Price.times(token0.derivedETH as BigDecimal) // return token0 per our token * ETH per token 0 @@ -118,7 +118,7 @@ export function getTrackedVolumeUSD( token1: Token, pair: Pair, ): BigDecimal { - let bundle = Bundle.load('1')! + let bundle = Bundle.load(Bytes.fromI32(1))! let price0 = token0.derivedETH.times(bundle.ethPrice) let price1 = token1.derivedETH.times(bundle.ethPrice) @@ -179,7 +179,7 @@ export function getTrackedLiquidityUSD( tokenAmount1: BigDecimal, token1: Token, ): BigDecimal { - let bundle = Bundle.load('1')! + let bundle = Bundle.load(Bytes.fromI32(1))! let price0 = token0.derivedETH.times(bundle.ethPrice) let price1 = token1.derivedETH.times(bundle.ethPrice) diff --git a/subgraph.yaml b/subgraph.yaml index fa437318..54eb178c 100644 --- a/subgraph.yaml +++ b/subgraph.yaml @@ -1,4 +1,4 @@ -specVersion: 0.0.4 +specVersion: 1.2.0 description: Uniswap is a decentralized protocol for automated token exchange on Ethereum. repository: https://github.com/Uniswap/uniswap-v2-subgraph schema: @@ -8,12 +8,13 @@ dataSources: name: Factory network: mainnet source: - address: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f' + address: "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f" abi: Factory startBlock: 10000834 + endBlock: 10100000 mapping: kind: ethereum/events - apiVersion: 0.0.7 + apiVersion: 0.0.9 language: wasm/assemblyscript file: ./src/mappings/factory.ts entities: @@ -31,6 +32,15 @@ dataSources: eventHandlers: - event: PairCreated(indexed address,indexed address,address,uint256) handler: handleNewPair + calls: + name0: ERC20[event.params.token0].name() + symbol0: ERC20[event.params.token0].symbol() + totalSupply0: ERC20[event.params.token1].totalSupply() + decimals0: ERC20[event.params.token0].decimals() + name1: ERC20[event.params.token1].name() + symbol1: ERC20[event.params.token1].symbol() + totalSupply1: ERC20[event.params.token1].totalSupply() + decimals1: ERC20[event.params.token1].decimals() templates: - kind: ethereum/contract name: Pair @@ -39,7 +49,7 @@ templates: abi: Pair mapping: kind: ethereum/events - apiVersion: 0.0.7 + apiVersion: 0.0.9 language: wasm/assemblyscript file: ./src/mappings/core.ts entities: