From 6694bfd0f373ce2d8de1296e8f22c2beb3704f81 Mon Sep 17 00:00:00 2001 From: Dmitri Tsumak Date: Mon, 17 Jan 2022 09:46:56 +0200 Subject: [PATCH 1/7] Whitelist stakewise sETH2 --- src/utils/pricing.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/pricing.ts b/src/utils/pricing.ts index 9b1e15af..a4e0bca4 100644 --- a/src/utils/pricing.ts +++ b/src/utils/pricing.ts @@ -29,7 +29,8 @@ export let WHITELIST_TOKENS: string[] = [ '0xdf5e0e81dff6faf3a7e52ba697820c5e32d806a8', // yCurv '0x956f47f50a910163d8bf957cf5846d573e7f87ca', // FEI '0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0', // MATIC - '0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9' // AAVE + '0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9', // AAVE + '0xfe2e637202056d30016725477c5da089ab0a043a' // sETH2 ] let STABLE_COINS: string[] = [ From 2e91f13fc09463add080cc355542c2a8c7660155 Mon Sep 17 00:00:00 2001 From: Dmitri Tsumak Date: Fri, 21 Jan 2022 21:01:57 +0200 Subject: [PATCH 2/7] Update graft block and base --- subgraph.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subgraph.yaml b/subgraph.yaml index 9626ba64..03459143 100644 --- a/subgraph.yaml +++ b/subgraph.yaml @@ -4,8 +4,8 @@ repository: https://github.com/Uniswap/uniswap-v3-subgraph schema: file: ./schema.graphql graft: - base: QmS13421u6qsbVdBCrZhdRaZw2wH67drwF3urmueJvvJ5P - block: 13591197 + base: QmZeCuoZeadgHkGwLwMeguyqUKz1WPWQYKcKyMCeQqGhsF + block: 12673736 dataSources: - kind: ethereum/contract name: Factory From c150eb1fa06321d6f3949e3d604d8d2f19da28c1 Mon Sep 17 00:00:00 2001 From: ianlapham Date: Fri, 11 Mar 2022 12:49:14 -0500 Subject: [PATCH 3/7] Refactor and clean code, add collect event logic --- package.json | 2 +- schema.graphql | 210 ++---------- src/mappings/core.ts | 526 ------------------------------- src/mappings/core/burn.ts | 87 +++++ src/mappings/core/collect.ts | 72 +++++ src/mappings/core/flash.ts | 9 + src/mappings/core/index.ts | 12 + src/mappings/core/initialize.ts | 29 ++ src/mappings/core/mint.ts | 109 +++++++ src/mappings/core/swap.ts | 180 +++++++++++ src/mappings/factory.ts | 22 +- src/mappings/position-manager.ts | 200 ------------ src/utils/constants.ts | 1 + src/utils/intervalUpdates.ts | 40 +-- src/utils/pricing.ts | 88 +++++- src/utils/tick.ts | 15 +- src/utils/tvl.ts | 68 ++++ subgraph.yaml | 41 +-- yarn.lock | 320 ++++++++++++++++--- 19 files changed, 978 insertions(+), 1053 deletions(-) delete mode 100644 src/mappings/core.ts create mode 100644 src/mappings/core/burn.ts create mode 100644 src/mappings/core/collect.ts create mode 100644 src/mappings/core/flash.ts create mode 100644 src/mappings/core/index.ts create mode 100644 src/mappings/core/initialize.ts create mode 100644 src/mappings/core/mint.ts create mode 100644 src/mappings/core/swap.ts delete mode 100644 src/mappings/position-manager.ts create mode 100644 src/utils/tvl.ts diff --git a/package.json b/package.json index 9a7bdda5..6d9106da 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "build": "graph build", "create-local": "graph create ianlapham/uniswap-v3 --node http://127.0.0.1:8020", "deploy-local": "graph deploy ianlapham/uniswap-v3 --debug --ipfs http://localhost:5001 --node http://127.0.0.1:8020", - "deploy": "graph deploy uniswap/uniswap-v3 --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/ --debug", + "deploy": "graph deploy ianlapham/v3-minimal --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/ --debug", "deploy-dev": "graph deploy sommelier/uniswap-v3 --ipfs http://35.197.14.14:5000/ --node http://35.197.14.14:8020/ --debug", "deploy-staging": "graph deploy $THE_GRAPH_GITHUB_USER/$THE_GRAPH_SUBGRAPH_NAME /Uniswap --ipfs https://api.staging.thegraph.com/ipfs/ --node https://api.staging.thegraph.com/deploy/", "watch-local": "graph deploy ianlapham/uniswap-v3 --watch --debug --node http://127.0.0.1:8020/ --ipfs http://localhost:5001" diff --git a/schema.graphql b/schema.graphql index a8f1d0a7..314f504d 100644 --- a/schema.graphql +++ b/schema.graphql @@ -6,15 +6,15 @@ type Factory @entity { # amoutn of transactions all time txCount: BigInt! # total volume all time in derived USD - totalVolumeUSD: BigDecimal! + volumeUSD: BigDecimal! # total volume all time in derived ETH - totalVolumeETH: BigDecimal! + volumeETH: BigDecimal! + # all volume even through less reliable USD values + volumeUSDUntracked: BigDecimal! # total swap fees all time in USD - totalFeesUSD: BigDecimal! + feesUSD: BigDecimal! # total swap fees all time in USD - totalFeesETH: BigDecimal! - # all volume even through less reliable USD values - untrackedVolumeUSD: BigDecimal! + feesETH: BigDecimal! # TVL derived in USD totalValueLockedUSD: BigDecimal! # TVL derived in ETH @@ -23,7 +23,6 @@ type Factory @entity { totalValueLockedUSDUntracked: BigDecimal! # TVL derived in ETH untracked totalValueLockedETHUntracked: BigDecimal! - # current owner of the factory owner: ID! } @@ -51,7 +50,7 @@ type Token @entity { # volume in derived USD volumeUSD: BigDecimal! # volume in USD even on pools with less reliable USD values - untrackedVolumeUSD: BigDecimal! + volumeUSDUntracked: BigDecimal! # fees in USD feesUSD: BigDecimal! # transactions across all pools that include this token @@ -62,8 +61,6 @@ type Token @entity { totalValueLocked: BigDecimal! # liquidity across all pools in derived USD totalValueLockedUSD: BigDecimal! - # TVL derived in USD untracked - totalValueLockedUSDUntracked: BigDecimal! # derived price in ETH derivedETH: BigDecimal! # pools token is in that are white listed for USD pricing @@ -108,27 +105,29 @@ type Pool @entity { # all time USD swapped volumeUSD: BigDecimal! # all time USD swapped, unfiltered for unreliable USD pools - untrackedVolumeUSD: BigDecimal! + volumeUSDUntracked: BigDecimal! # fees in USD feesUSD: BigDecimal! # all time number of transactions txCount: BigInt! - # all time fees collected token0 - collectedFeesToken0: BigDecimal! - # all time fees collected token1 - collectedFeesToken1: BigDecimal! - # all time fees collected derived USD - collectedFeesUSD: BigDecimal! # total token 0 across all ticks totalValueLockedToken0: BigDecimal! # total token 1 across all ticks totalValueLockedToken1: BigDecimal! - # tvl derived ETH + # TVL derived ETH totalValueLockedETH: BigDecimal! - # tvl USD + # TVL USD totalValueLockedUSD: BigDecimal! + # TVL derived in ETH untracked + totalValueLockedETHUntracked: BigDecimal! # TVL derived in USD untracked totalValueLockedUSDUntracked: BigDecimal! + # all time fees collected token0 + collectedFeesToken0: BigDecimal! + # all time fees collected token1 + collectedFeesToken1: BigDecimal! + # all time fees collected derived USD + collectedFeesUSD: BigDecimal! # Fields used to help derived relationship liquidityProviderCount: BigInt! # used to detect new exchanges # hourly snapshots of pool data @@ -150,6 +149,10 @@ type Tick @entity { poolAddress: String # tick index tickIdx: BigInt! + # created time + createdAtTimestamp: BigInt! + # created block + createdAtBlockNumber: BigInt! # pointer to pool pool: Pool! # total liquidity pool has as tick lower or upper @@ -160,110 +163,6 @@ type Tick @entity { price0: BigDecimal! # calculated price of token1 of tick within this pool - constant price1: BigDecimal! - # lifetime volume of token0 with this tick in range - volumeToken0: BigDecimal! - # lifetime volume of token1 with this tick in range - volumeToken1: BigDecimal! - # lifetime volume in derived USD with this tick in range - volumeUSD: BigDecimal! - # lifetime volume in untracked USD with this tick in range - untrackedVolumeUSD: BigDecimal! - # fees in USD - feesUSD: BigDecimal! - # all time collected fees in token0 - collectedFeesToken0: BigDecimal! - # all time collected fees in token1 - collectedFeesToken1: BigDecimal! - # all time collected fees in USD - collectedFeesUSD: BigDecimal! - # created time - createdAtTimestamp: BigInt! - # created block - createdAtBlockNumber: BigInt! - # Fields used to help derived relationship - liquidityProviderCount: BigInt! # used to detect new exchanges - # derived fields - # swaps: [Swap!]! @derivedFrom(field: "tick") - # vars needed for fee computation - feeGrowthOutside0X128: BigInt! - feeGrowthOutside1X128: BigInt! -} - -type Position @entity { - # Positions created through NonfungiblePositionManager - # NFT token id - id: ID! - # owner of the NFT - owner: Bytes! - # pool position is within - pool: Pool! - # allow indexing by tokens - token0: Token! - # allow indexing by tokens - token1: Token! - # lower tick of the position - tickLower: Tick! - # upper tick of the position - tickUpper: Tick! - # total position liquidity - liquidity: BigInt! - # amount of token 0 ever deposited to position - depositedToken0: BigDecimal! - # amount of token 1 ever deposited to position - depositedToken1: BigDecimal! - # amount of token 0 ever withdrawn from position (without fees) - withdrawnToken0: BigDecimal! - # amount of token 1 ever withdrawn from position (without fees) - withdrawnToken1: BigDecimal! - # all time collected fees in token0 - collectedFeesToken0: BigDecimal! - # all time collected fees in token1 - collectedFeesToken1: BigDecimal! - # Total amount deposited in terms of USD - amountDepositedUSD: BigDecimal! - # Total amount withdrawn in terms of USD - amountWithdrawnUSD: BigDecimal! - # Total amount collected in terms of USD - amountCollectedUSD: BigDecimal! - # tx in which the position was initialized - transaction: Transaction! - # vars needed for fee computation - feeGrowthInside0LastX128: BigInt! - feeGrowthInside1LastX128: BigInt! -} - -type PositionSnapshot @entity { - # # - id: ID! - # owner of the NFT - owner: Bytes! - # pool the position is within - pool: Pool! - # position of which the snap was taken of - position: Position! - # block in which the snap was created - blockNumber: BigInt! - # timestamp of block in which the snap was created - timestamp: BigInt! - # total position liquidity - liquidity: BigInt! - # amount of token 0 ever deposited to position - depositedToken0: BigDecimal! - # amount of token 1 ever deposited to position - depositedToken1: BigDecimal! - # amount of token 0 ever withdrawn from position (without fees) - withdrawnToken0: BigDecimal! - # amount of token 1 ever withdrawn from position (without fees) - withdrawnToken1: BigDecimal! - # all time collected fees in token0 - collectedFeesToken0: BigDecimal! - # all time collected fees in token1 - collectedFeesToken1: BigDecimal! - # tx in which the snapshot was initialized - transaction: Transaction! - # internal vars needed for fee computation - feeGrowthInside0LastX128: BigInt! - feeGrowthInside1LastX128: BigInt! } type Transaction @entity { @@ -449,12 +348,12 @@ type UniswapDayData @entity { volumeUSD: BigDecimal! # total daily volume in Uniswap derived in terms of USD untracked volumeUSDUntracked: BigDecimal! + # tvl in terms of USD + totalValueLockedUSD: BigDecimal! # fees in USD feesUSD: BigDecimal! # number of daily transactions txCount: BigInt! - # tvl in terms of USD - tvlUSD: BigDecimal! } # Data accumulated and condensed into day stats for each pool @@ -479,8 +378,8 @@ type PoolDayData @entity { feeGrowthGlobal0X128: BigInt! # tracker for global fee growth feeGrowthGlobal1X128: BigInt! - # tvl derived in USD at end of period - tvlUSD: BigDecimal! + # TVL derived in USD at end of period + totalValueLockedUSD: BigDecimal! # volume in token0 volumeToken0: BigDecimal! # volume in token1 @@ -524,7 +423,7 @@ type PoolHourData @entity { # tracker for global fee growth feeGrowthGlobal1X128: BigInt! # tvl derived in USD at end of period - tvlUSD: BigDecimal! + totalValueLockedUSD: BigDecimal! # volume in token0 volumeToken0: BigDecimal! # volume in token1 @@ -545,57 +444,6 @@ type PoolHourData @entity { close: BigDecimal! } -type TickHourData @entity { - # format: -- - id: ID! - # unix timestamp for start of hour - periodStartUnix: Int! - # pointer to pool - pool: Pool! - # pointer to tick - tick: Tick! - # total liquidity pool has as tick lower or upper at end of period - liquidityGross: BigInt! - # how much liquidity changes when tick crossed at end of period - liquidityNet: BigInt! - # hourly volume of token0 with this tick in range - volumeToken0: BigDecimal! - # hourly volume of token1 with this tick in range - volumeToken1: BigDecimal! - # hourly volume in derived USD with this tick in range - volumeUSD: BigDecimal! - # fees in USD - feesUSD: BigDecimal! -} - -# Data accumulated and condensed into day stats for each exchange -# Note: this entity gets saved only if there is a change during the day -type TickDayData @entity { - # format: -- - id: ID! - # timestamp rounded to current day by dividing by 86400 - date: Int! - # pointer to pool - pool: Pool! - # pointer to tick - tick: Tick! - # total liquidity pool has as tick lower or upper at end of period - liquidityGross: BigInt! - # how much liquidity changes when tick crossed at end of period - liquidityNet: BigInt! - # hourly volume of token0 with this tick in range - volumeToken0: BigDecimal! - # hourly volume of token1 with this tick in range - volumeToken1: BigDecimal! - # hourly volume in derived USD with this tick in range - volumeUSD: BigDecimal! - # fees in USD - feesUSD: BigDecimal! - # vars needed for fee computation - feeGrowthOutside0X128: BigInt! - feeGrowthOutside1X128: BigInt! -} - type TokenDayData @entity { # token address concatendated with date id: ID! @@ -608,7 +456,7 @@ type TokenDayData @entity { # volume in derived USD volumeUSD: BigDecimal! # volume in USD even on pools with less reliable USD values - untrackedVolumeUSD: BigDecimal! + volumeUSDUntracked: BigDecimal! # liquidity across all pools in token units totalValueLocked: BigDecimal! # liquidity across all pools in derived USD @@ -639,7 +487,7 @@ type TokenHourData @entity { # volume in derived USD volumeUSD: BigDecimal! # volume in USD even on pools with less reliable USD values - untrackedVolumeUSD: BigDecimal! + volumeUSDUntracked: BigDecimal! # liquidity across all pools in token units totalValueLocked: BigDecimal! # liquidity across all pools in derived USD diff --git a/src/mappings/core.ts b/src/mappings/core.ts deleted file mode 100644 index fea22609..00000000 --- a/src/mappings/core.ts +++ /dev/null @@ -1,526 +0,0 @@ -/* eslint-disable prefer-const */ -import { Bundle, Burn, Factory, Mint, Pool, Swap, Tick, Token } from '../types/schema' -import { Pool as PoolABI } from '../types/Factory/Pool' -import { BigDecimal, BigInt, ethereum } from '@graphprotocol/graph-ts' -import { - Burn as BurnEvent, - Flash as FlashEvent, - Initialize, - Mint as MintEvent, - Swap as SwapEvent -} from '../types/templates/Pool/Pool' -import { convertTokenToDecimal, loadTransaction, safeDiv } from '../utils' -import { FACTORY_ADDRESS, ONE_BI, ZERO_BD, ZERO_BI } from '../utils/constants' -import { findEthPerToken, getEthPriceInUSD, getTrackedAmountUSD, sqrtPriceX96ToTokenPrices } from '../utils/pricing' -import { - updatePoolDayData, - updatePoolHourData, - updateTickDayData, - updateTokenDayData, - updateTokenHourData, - updateUniswapDayData -} from '../utils/intervalUpdates' -import { createTick, feeTierToTickSpacing } from '../utils/tick' - -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) - - // update ETH price now that prices could have changed - let bundle = Bundle.load('1') - bundle.ethPriceUSD = getEthPriceInUSD() - bundle.save() - - updatePoolDayData(event) - updatePoolHourData(event) - - // update token prices - token0.derivedETH = findEthPerToken(token0 as Token) - token1.derivedETH = findEthPerToken(token1 as Token) - token0.save() - token1.save() -} - -export function handleMint(event: MintEvent): void { - let bundle = Bundle.load('1') - let poolAddress = event.address.toHexString() - let pool = Pool.load(poolAddress) - let factory = Factory.load(FACTORY_ADDRESS) - - let token0 = Token.load(pool.token0) - let token1 = Token.load(pool.token1) - let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals) - let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals) - - let amountUSD = amount0 - .times(token0.derivedETH.times(bundle.ethPriceUSD)) - .plus(amount1.times(token1.derivedETH.times(bundle.ethPriceUSD))) - - // reset tvl aggregates until new amounts calculated - factory.totalValueLockedETH = factory.totalValueLockedETH.minus(pool.totalValueLockedETH) - - // update globals - factory.txCount = factory.txCount.plus(ONE_BI) - - // update token0 data - token0.txCount = token0.txCount.plus(ONE_BI) - token0.totalValueLocked = token0.totalValueLocked.plus(amount0) - token0.totalValueLockedUSD = token0.totalValueLocked.times(token0.derivedETH.times(bundle.ethPriceUSD)) - - // update token1 data - token1.txCount = token1.txCount.plus(ONE_BI) - token1.totalValueLocked = token1.totalValueLocked.plus(amount1) - token1.totalValueLockedUSD = token1.totalValueLocked.times(token1.derivedETH.times(bundle.ethPriceUSD)) - - // pool data - pool.txCount = pool.txCount.plus(ONE_BI) - - // Pools liquidity tracks the currently active liquidity given pools current tick. - // We only want to update it on mint if the new position includes the current tick. - if ( - pool.tick !== null && - BigInt.fromI32(event.params.tickLower).le(pool.tick as BigInt) && - BigInt.fromI32(event.params.tickUpper).gt(pool.tick as BigInt) - ) { - pool.liquidity = pool.liquidity.plus(event.params.amount) - } - - pool.totalValueLockedToken0 = pool.totalValueLockedToken0.plus(amount0) - pool.totalValueLockedToken1 = pool.totalValueLockedToken1.plus(amount1) - pool.totalValueLockedETH = pool.totalValueLockedToken0 - .times(token0.derivedETH) - .plus(pool.totalValueLockedToken1.times(token1.derivedETH)) - pool.totalValueLockedUSD = pool.totalValueLockedETH.times(bundle.ethPriceUSD) - - // reset aggregates with new amounts - factory.totalValueLockedETH = factory.totalValueLockedETH.plus(pool.totalValueLockedETH) - factory.totalValueLockedUSD = factory.totalValueLockedETH.times(bundle.ethPriceUSD) - - let transaction = loadTransaction(event) - let mint = new Mint(transaction.id.toString() + '#' + pool.txCount.toString()) - 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 - mint.amount = event.params.amount - mint.amount0 = amount0 - mint.amount1 = amount1 - mint.amountUSD = amountUSD - mint.tickLower = BigInt.fromI32(event.params.tickLower) - mint.tickUpper = BigInt.fromI32(event.params.tickUpper) - mint.logIndex = event.logIndex - - // tick entities - let lowerTickIdx = event.params.tickLower - let upperTickIdx = event.params.tickUpper - - 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) - } - - if (upperTick === null) { - upperTick = createTick(upperTickId, upperTickIdx, pool.id, event) - } - - let amount = event.params.amount - lowerTick.liquidityGross = lowerTick.liquidityGross.plus(amount) - lowerTick.liquidityNet = lowerTick.liquidityNet.plus(amount) - upperTick.liquidityGross = upperTick.liquidityGross.plus(amount) - upperTick.liquidityNet = upperTick.liquidityNet.minus(amount) - - // TODO: Update Tick's volume, fees, and liquidity provider count. Computing these on the tick - // level requires reimplementing some of the swapping code from v3-core. - - updateUniswapDayData(event) - updatePoolDayData(event) - updatePoolHourData(event) - updateTokenDayData(token0 as Token, event) - updateTokenDayData(token1 as Token, event) - updateTokenHourData(token0 as Token, event) - updateTokenHourData(token1 as Token, event) - - token0.save() - token1.save() - pool.save() - factory.save() - mint.save() - - // Update inner tick vars and save the ticks - updateTickFeeVarsAndSave(lowerTick!, event) - updateTickFeeVarsAndSave(upperTick!, event) -} - -export function handleBurn(event: BurnEvent): void { - let bundle = Bundle.load('1') - let poolAddress = event.address.toHexString() - let pool = Pool.load(poolAddress) - let factory = Factory.load(FACTORY_ADDRESS) - - let token0 = Token.load(pool.token0) - let token1 = Token.load(pool.token1) - let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals) - let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals) - - let amountUSD = amount0 - .times(token0.derivedETH.times(bundle.ethPriceUSD)) - .plus(amount1.times(token1.derivedETH.times(bundle.ethPriceUSD))) - - // reset tvl aggregates until new amounts calculated - factory.totalValueLockedETH = factory.totalValueLockedETH.minus(pool.totalValueLockedETH) - - // update globals - factory.txCount = factory.txCount.plus(ONE_BI) - - // update token0 data - token0.txCount = token0.txCount.plus(ONE_BI) - token0.totalValueLocked = token0.totalValueLocked.minus(amount0) - token0.totalValueLockedUSD = token0.totalValueLocked.times(token0.derivedETH.times(bundle.ethPriceUSD)) - - // update token1 data - token1.txCount = token1.txCount.plus(ONE_BI) - token1.totalValueLocked = token1.totalValueLocked.minus(amount1) - token1.totalValueLockedUSD = token1.totalValueLocked.times(token1.derivedETH.times(bundle.ethPriceUSD)) - - // pool data - pool.txCount = pool.txCount.plus(ONE_BI) - // Pools liquidity tracks the currently active liquidity given pools current tick. - // We only want to update it on burn if the position being burnt includes the current tick. - if ( - pool.tick !== null && - BigInt.fromI32(event.params.tickLower).le(pool.tick as BigInt) && - BigInt.fromI32(event.params.tickUpper).gt(pool.tick as BigInt) - ) { - pool.liquidity = pool.liquidity.minus(event.params.amount) - } - - pool.totalValueLockedToken0 = pool.totalValueLockedToken0.minus(amount0) - pool.totalValueLockedToken1 = pool.totalValueLockedToken1.minus(amount1) - pool.totalValueLockedETH = pool.totalValueLockedToken0 - .times(token0.derivedETH) - .plus(pool.totalValueLockedToken1.times(token1.derivedETH)) - pool.totalValueLockedUSD = pool.totalValueLockedETH.times(bundle.ethPriceUSD) - - // reset aggregates with new amounts - factory.totalValueLockedETH = factory.totalValueLockedETH.plus(pool.totalValueLockedETH) - factory.totalValueLockedUSD = factory.totalValueLockedETH.times(bundle.ethPriceUSD) - - // burn entity - let transaction = loadTransaction(event) - let burn = new Burn(transaction.id + '#' + pool.txCount.toString()) - 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 - burn.amount0 = amount0 - burn.amount1 = amount1 - burn.amountUSD = amountUSD - burn.tickLower = BigInt.fromI32(event.params.tickLower) - burn.tickUpper = BigInt.fromI32(event.params.tickUpper) - burn.logIndex = event.logIndex - - // tick entities - 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) - let amount = event.params.amount - lowerTick.liquidityGross = lowerTick.liquidityGross.minus(amount) - lowerTick.liquidityNet = lowerTick.liquidityNet.minus(amount) - upperTick.liquidityGross = upperTick.liquidityGross.minus(amount) - upperTick.liquidityNet = upperTick.liquidityNet.plus(amount) - - updateUniswapDayData(event) - updatePoolDayData(event) - updatePoolHourData(event) - updateTokenDayData(token0 as Token, event) - updateTokenDayData(token1 as Token, event) - updateTokenHourData(token0 as Token, event) - updateTokenHourData(token1 as Token, event) - updateTickFeeVarsAndSave(lowerTick!, event) - updateTickFeeVarsAndSave(upperTick!, event) - - token0.save() - token1.save() - pool.save() - factory.save() - burn.save() -} - -export function handleSwap(event: SwapEvent): void { - let bundle = Bundle.load('1') - let factory = Factory.load(FACTORY_ADDRESS) - let pool = Pool.load(event.address.toHexString()) - - // hot fix for bad pricing - if (pool.id == '0x9663f2ca0454accad3e094448ea6f77443880454') { - return - } - - let token0 = Token.load(pool.token0) - let token1 = Token.load(pool.token1) - - let oldTick = pool.tick! - - // amounts - 0/1 are token deltas: can be positive or negative - let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals) - let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals) - - // need absolute amounts for volume - let amount0Abs = amount0 - if (amount0.lt(ZERO_BD)) { - amount0Abs = amount0.times(BigDecimal.fromString('-1')) - } - let amount1Abs = amount1 - if (amount1.lt(ZERO_BD)) { - amount1Abs = amount1.times(BigDecimal.fromString('-1')) - } - - let amount0ETH = amount0Abs.times(token0.derivedETH) - let amount1ETH = amount1Abs.times(token1.derivedETH) - let amount0USD = amount0ETH.times(bundle.ethPriceUSD) - let amount1USD = amount1ETH.times(bundle.ethPriceUSD) - - // get amount that should be tracked only - div 2 because cant count both input and output as volume - let amountTotalUSDTracked = getTrackedAmountUSD(amount0Abs, token0 as Token, amount1Abs, token1 as Token).div( - BigDecimal.fromString('2') - ) - let amountTotalETHTracked = safeDiv(amountTotalUSDTracked, bundle.ethPriceUSD) - let amountTotalUSDUntracked = amount0USD.plus(amount1USD).div(BigDecimal.fromString('2')) - - let feesETH = amountTotalETHTracked.times(pool.feeTier.toBigDecimal()).div(BigDecimal.fromString('1000000')) - let feesUSD = amountTotalUSDTracked.times(pool.feeTier.toBigDecimal()).div(BigDecimal.fromString('1000000')) - - // global updates - factory.txCount = factory.txCount.plus(ONE_BI) - factory.totalVolumeETH = factory.totalVolumeETH.plus(amountTotalETHTracked) - factory.totalVolumeUSD = factory.totalVolumeUSD.plus(amountTotalUSDTracked) - factory.untrackedVolumeUSD = factory.untrackedVolumeUSD.plus(amountTotalUSDUntracked) - factory.totalFeesETH = factory.totalFeesETH.plus(feesETH) - factory.totalFeesUSD = factory.totalFeesUSD.plus(feesUSD) - - // reset aggregate tvl before individual pool tvl updates - let currentPoolTvlETH = pool.totalValueLockedETH - factory.totalValueLockedETH = factory.totalValueLockedETH.minus(currentPoolTvlETH) - - // pool volume - pool.volumeToken0 = pool.volumeToken0.plus(amount0Abs) - pool.volumeToken1 = pool.volumeToken1.plus(amount1Abs) - pool.volumeUSD = pool.volumeUSD.plus(amountTotalUSDTracked) - pool.untrackedVolumeUSD = pool.untrackedVolumeUSD.plus(amountTotalUSDUntracked) - pool.feesUSD = pool.feesUSD.plus(feesUSD) - pool.txCount = pool.txCount.plus(ONE_BI) - - // Update the pool with the new active liquidity, price, and tick. - pool.liquidity = event.params.liquidity - pool.tick = BigInt.fromI32(event.params.tick as i32) - pool.sqrtPrice = event.params.sqrtPriceX96 - pool.totalValueLockedToken0 = pool.totalValueLockedToken0.plus(amount0) - pool.totalValueLockedToken1 = pool.totalValueLockedToken1.plus(amount1) - - // update token0 data - token0.volume = token0.volume.plus(amount0Abs) - token0.totalValueLocked = token0.totalValueLocked.plus(amount0) - token0.volumeUSD = token0.volumeUSD.plus(amountTotalUSDTracked) - token0.untrackedVolumeUSD = token0.untrackedVolumeUSD.plus(amountTotalUSDUntracked) - token0.feesUSD = token0.feesUSD.plus(feesUSD) - token0.txCount = token0.txCount.plus(ONE_BI) - - // update token1 data - token1.volume = token1.volume.plus(amount1Abs) - token1.totalValueLocked = token1.totalValueLocked.plus(amount1) - token1.volumeUSD = token1.volumeUSD.plus(amountTotalUSDTracked) - token1.untrackedVolumeUSD = token1.untrackedVolumeUSD.plus(amountTotalUSDUntracked) - token1.feesUSD = token1.feesUSD.plus(feesUSD) - token1.txCount = token1.txCount.plus(ONE_BI) - - // updated pool ratess - let prices = sqrtPriceX96ToTokenPrices(pool.sqrtPrice, token0 as Token, token1 as Token) - pool.token0Price = prices[0] - pool.token1Price = prices[1] - pool.save() - - // update USD pricing - bundle.ethPriceUSD = getEthPriceInUSD() - bundle.save() - token0.derivedETH = findEthPerToken(token0 as Token) - token1.derivedETH = findEthPerToken(token1 as Token) - - /** - * Things afffected by new USD rates - */ - pool.totalValueLockedETH = pool.totalValueLockedToken0 - .times(token0.derivedETH) - .plus(pool.totalValueLockedToken1.times(token1.derivedETH)) - pool.totalValueLockedUSD = pool.totalValueLockedETH.times(bundle.ethPriceUSD) - - factory.totalValueLockedETH = factory.totalValueLockedETH.plus(pool.totalValueLockedETH) - factory.totalValueLockedUSD = factory.totalValueLockedETH.times(bundle.ethPriceUSD) - - token0.totalValueLockedUSD = token0.totalValueLocked.times(token0.derivedETH).times(bundle.ethPriceUSD) - token1.totalValueLockedUSD = token1.totalValueLocked.times(token1.derivedETH).times(bundle.ethPriceUSD) - - // create Swap event - let transaction = loadTransaction(event) - let swap = new Swap(transaction.id + '#' + pool.txCount.toString()) - 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 - swap.amount0 = amount0 - swap.amount1 = amount1 - swap.amountUSD = amountTotalUSDTracked - swap.tick = BigInt.fromI32(event.params.tick as i32) - swap.sqrtPriceX96 = event.params.sqrtPriceX96 - swap.logIndex = event.logIndex - - // update fee growth - let poolContract = PoolABI.bind(event.address) - let feeGrowthGlobal0X128 = poolContract.feeGrowthGlobal0X128() - let feeGrowthGlobal1X128 = poolContract.feeGrowthGlobal1X128() - pool.feeGrowthGlobal0X128 = feeGrowthGlobal0X128 as BigInt - pool.feeGrowthGlobal1X128 = feeGrowthGlobal1X128 as BigInt - - // interval data - let uniswapDayData = updateUniswapDayData(event) - let poolDayData = updatePoolDayData(event) - let poolHourData = updatePoolHourData(event) - let token0DayData = updateTokenDayData(token0 as Token, event) - let token1DayData = updateTokenDayData(token1 as Token, event) - let token0HourData = updateTokenHourData(token0 as Token, event) - let token1HourData = updateTokenHourData(token1 as Token, event) - - // update volume metrics - uniswapDayData.volumeETH = uniswapDayData.volumeETH.plus(amountTotalETHTracked) - uniswapDayData.volumeUSD = uniswapDayData.volumeUSD.plus(amountTotalUSDTracked) - uniswapDayData.feesUSD = uniswapDayData.feesUSD.plus(feesUSD) - - poolDayData.volumeUSD = poolDayData.volumeUSD.plus(amountTotalUSDTracked) - poolDayData.volumeToken0 = poolDayData.volumeToken0.plus(amount0Abs) - poolDayData.volumeToken1 = poolDayData.volumeToken1.plus(amount1Abs) - poolDayData.feesUSD = poolDayData.feesUSD.plus(feesUSD) - - poolHourData.volumeUSD = poolHourData.volumeUSD.plus(amountTotalUSDTracked) - poolHourData.volumeToken0 = poolHourData.volumeToken0.plus(amount0Abs) - poolHourData.volumeToken1 = poolHourData.volumeToken1.plus(amount1Abs) - poolHourData.feesUSD = poolHourData.feesUSD.plus(feesUSD) - - token0DayData.volume = token0DayData.volume.plus(amount0Abs) - token0DayData.volumeUSD = token0DayData.volumeUSD.plus(amountTotalUSDTracked) - token0DayData.untrackedVolumeUSD = token0DayData.untrackedVolumeUSD.plus(amountTotalUSDTracked) - token0DayData.feesUSD = token0DayData.feesUSD.plus(feesUSD) - - token0HourData.volume = token0HourData.volume.plus(amount0Abs) - token0HourData.volumeUSD = token0HourData.volumeUSD.plus(amountTotalUSDTracked) - token0HourData.untrackedVolumeUSD = token0HourData.untrackedVolumeUSD.plus(amountTotalUSDTracked) - token0HourData.feesUSD = token0HourData.feesUSD.plus(feesUSD) - - token1DayData.volume = token1DayData.volume.plus(amount1Abs) - token1DayData.volumeUSD = token1DayData.volumeUSD.plus(amountTotalUSDTracked) - token1DayData.untrackedVolumeUSD = token1DayData.untrackedVolumeUSD.plus(amountTotalUSDTracked) - token1DayData.feesUSD = token1DayData.feesUSD.plus(feesUSD) - - token1HourData.volume = token1HourData.volume.plus(amount1Abs) - token1HourData.volumeUSD = token1HourData.volumeUSD.plus(amountTotalUSDTracked) - token1HourData.untrackedVolumeUSD = token1HourData.untrackedVolumeUSD.plus(amountTotalUSDTracked) - token1HourData.feesUSD = token1HourData.feesUSD.plus(feesUSD) - - swap.save() - token0DayData.save() - token1DayData.save() - uniswapDayData.save() - poolDayData.save() - factory.save() - pool.save() - token0.save() - token1.save() - - // Update inner vars of current or crossed ticks - let newTick = pool.tick! - let tickSpacing = feeTierToTickSpacing(pool.feeTier) - let modulo = newTick.mod(tickSpacing) - if (modulo.equals(ZERO_BI)) { - // Current tick is initialized and needs to be updated - loadTickUpdateFeeVarsAndSave(newTick.toI32(), event) - } - - let numIters = oldTick - .minus(newTick) - .abs() - .div(tickSpacing) - - if (numIters.gt(BigInt.fromI32(100))) { - // In case more than 100 ticks need to be updated ignore the update in - // order to avoid timeouts. From testing this behavior occurs only upon - // pool initialization. This should not be a big issue as the ticks get - // updated later. For early users this error also disappears when calling - // collect - } else if (newTick.gt(oldTick)) { - let firstInitialized = oldTick.plus(tickSpacing.minus(modulo)) - for (let i = firstInitialized; i.le(newTick); i = i.plus(tickSpacing)) { - loadTickUpdateFeeVarsAndSave(i.toI32(), event) - } - } else if (newTick.lt(oldTick)) { - let firstInitialized = oldTick.minus(modulo) - for (let i = firstInitialized; i.ge(newTick); i = i.minus(tickSpacing)) { - loadTickUpdateFeeVarsAndSave(i.toI32(), event) - } - } -} - -export function handleFlash(event: FlashEvent): void { - // update fee growth - let pool = Pool.load(event.address.toHexString()) - let poolContract = PoolABI.bind(event.address) - let feeGrowthGlobal0X128 = poolContract.feeGrowthGlobal0X128() - let feeGrowthGlobal1X128 = poolContract.feeGrowthGlobal1X128() - pool.feeGrowthGlobal0X128 = feeGrowthGlobal0X128 as BigInt - pool.feeGrowthGlobal1X128 = feeGrowthGlobal1X128 as BigInt - pool.save() -} - -function updateTickFeeVarsAndSave(tick: Tick, event: ethereum.Event): void { - let poolAddress = event.address - // not all ticks are initialized so obtaining null is expected behavior - let poolContract = PoolABI.bind(poolAddress) - let tickResult = poolContract.ticks(tick.tickIdx.toI32()) - tick.feeGrowthOutside0X128 = tickResult.value2 - tick.feeGrowthOutside1X128 = tickResult.value3 - tick.save() - - updateTickDayData(tick!, event) -} - -function loadTickUpdateFeeVarsAndSave(tickId: i32, event: ethereum.Event): void { - let poolAddress = event.address - let tick = Tick.load( - poolAddress - .toHexString() - .concat('#') - .concat(tickId.toString()) - ) - if (tick !== null) { - updateTickFeeVarsAndSave(tick!, event) - } -} diff --git a/src/mappings/core/burn.ts b/src/mappings/core/burn.ts new file mode 100644 index 00000000..a5898c77 --- /dev/null +++ b/src/mappings/core/burn.ts @@ -0,0 +1,87 @@ +/* eslint-disable prefer-const */ +import { Bundle, Factory, Pool, Burn, Token } from '../../types/schema' +import { BigInt } from '@graphprotocol/graph-ts' +import { Burn as BurnEvent } from '../../types/templates/Pool/Pool' +import { convertTokenToDecimal, loadTransaction } from '../../utils' +import { FACTORY_ADDRESS, ONE_BI } from '../../utils/constants' +import { updateDerivedTVLAmounts } from '../../utils/tvl' +import { + updatePoolDayData, + updatePoolHourData, + updateTokenDayData, + updateTokenHourData, + updateUniswapDayData +} from '../../utils/intervalUpdates' + +export function handleBurn(event: BurnEvent): void { + let bundle = Bundle.load('1') + let poolAddress = event.address.toHexString() + let pool = Pool.load(poolAddress) + let factory = Factory.load(FACTORY_ADDRESS) + + // Parse amounts. + let token0 = Token.load(pool.token0) + let token1 = Token.load(pool.token1) + let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals) + let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals) + let amountUSD = amount0 + .times(token0.derivedETH.times(bundle.ethPriceUSD)) + .plus(amount1.times(token1.derivedETH.times(bundle.ethPriceUSD))) + + // Transaction count updates. + token0.txCount = token0.txCount.plus(ONE_BI) + token1.txCount = token1.txCount.plus(ONE_BI) + pool.txCount = pool.txCount.plus(ONE_BI) + factory.txCount = factory.txCount.plus(ONE_BI) + + // Update TVL values. + let oldPoolTotalValueLockedETH = pool.totalValueLockedETH + let oldPoolTVLETHUntracked = pool.totalValueLockedETHUntracked + token0.totalValueLocked = token0.totalValueLocked.minus(amount0) + token1.totalValueLocked = token1.totalValueLocked.minus(amount1) + pool.totalValueLockedToken0 = pool.totalValueLockedToken0.minus(amount0) + pool.totalValueLockedToken1 = pool.totalValueLockedToken1.minus(amount1) + updateDerivedTVLAmounts(pool as Pool, factory as Factory, oldPoolTotalValueLockedETH, oldPoolTVLETHUntracked) + + // Pools liquidity tracks the currently active liquidity given pools current tick. + // We only want to update it on burn if the position being burnt includes the current tick. + if ( + pool.tick !== null && + BigInt.fromI32(event.params.tickLower).le(pool.tick as BigInt) && + BigInt.fromI32(event.params.tickUpper).gt(pool.tick as BigInt) + ) { + pool.liquidity = pool.liquidity.minus(event.params.amount) + } + + // Burn entities. + let transaction = loadTransaction(event) + let burn = new Burn(transaction.id + '#' + pool.txCount.toString()) + 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 + burn.amount0 = amount0 + burn.amount1 = amount1 + burn.amountUSD = amountUSD + burn.tickLower = BigInt.fromI32(event.params.tickLower) + burn.tickUpper = BigInt.fromI32(event.params.tickUpper) + burn.logIndex = event.logIndex + + updateUniswapDayData(event) + updatePoolDayData(event) + updatePoolHourData(event) + updateTokenDayData(token0 as Token, event) + updateTokenDayData(token1 as Token, event) + updateTokenHourData(token0 as Token, event) + updateTokenHourData(token1 as Token, event) + + token0.save() + token1.save() + pool.save() + factory.save() + burn.save() +} diff --git a/src/mappings/core/collect.ts b/src/mappings/core/collect.ts new file mode 100644 index 00000000..41b33744 --- /dev/null +++ b/src/mappings/core/collect.ts @@ -0,0 +1,72 @@ +/* eslint-disable prefer-const */ +import { Collect, Factory, Pool, Token } from '../../types/schema' +import { Collect as CollectEvent } from '../../types/templates/Pool/Pool' +import { convertTokenToDecimal, loadTransaction } from '../../utils' +import { FACTORY_ADDRESS, ONE_BI } from '../../utils/constants' +import { AmountType, getAdjustedAmounts } from '../../utils/pricing' +import { BigInt } from '@graphprotocol/graph-ts' +import { updateDerivedTVLAmounts } from '../../utils/tvl' + +export function handleCollect(event: CollectEvent): boolean { + // update fee growth + let pool = Pool.load(event.address.toHexString()) + let factory = Factory.load(FACTORY_ADDRESS) + let token0 = Token.load(pool.token0) + let token1 = Token.load(pool.token1) + let transaction = loadTransaction(event) + + // Get formatted amounts collected. + let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals) + let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals) + let amounts: AmountType = getAdjustedAmounts( + // Used for USD in Collect event. + pool.totalValueLockedToken0, + token0 as Token, + pool.totalValueLockedToken1, + token1 as Token + ) + + // Adjust pool TVL based on amount collected. + let oldPoolTVLETH = pool.totalValueLockedETH + let oldPoolTVLETHUntracked = pool.totalValueLockedETHUntracked + pool.totalValueLockedToken0 = pool.totalValueLockedToken0.minus(amount0) + pool.totalValueLockedToken1 = pool.totalValueLockedToken1.minus(amount1) + token0.totalValueLocked = token0.totalValueLocked.minus(amount0) + token1.totalValueLocked = token1.totalValueLocked.minus(amount1) + updateDerivedTVLAmounts(pool as Pool, factory as Factory, oldPoolTVLETH, oldPoolTVLETHUntracked) + + // Update aggregate fee collection values. + pool.collectedFeesToken0 = pool.collectedFeesToken0.plus(amount0) + pool.collectedFeesToken1 = pool.collectedFeesToken1.plus(amount1) + pool.collectedFeesUSD = pool.collectedFeesUSD.plus(amounts.usd) + + // Update transaction counts. + factory.txCount = factory.txCount.plus(ONE_BI) + token0.txCount = token0.txCount.plus(ONE_BI) + token1.txCount = token1.txCount.plus(ONE_BI) + pool.txCount = pool.txCount.plus(ONE_BI) + + let collectID = event.transaction.hash + .toString() + .concat('-') + .concat(event.logIndex.toString()) + let collect = new Collect(collectID) + collect.transaction = transaction.id + collect.timestamp = event.block.timestamp + collect.pool = pool.id + collect.owner = event.params.owner + collect.amount0 = amount0 + collect.amount1 = amount1 + collect.amountUSD = amounts.usd + collect.tickLower = BigInt.fromI32(event.params.tickLower) + collect.tickUpper = BigInt.fromI32(event.params.tickUpper) + collect.logIndex = event.logIndex + + token0.save() + token1.save() + factory.save() + pool.save() + collect.save() + + return true +} diff --git a/src/mappings/core/flash.ts b/src/mappings/core/flash.ts new file mode 100644 index 00000000..6fc2fd62 --- /dev/null +++ b/src/mappings/core/flash.ts @@ -0,0 +1,9 @@ +/* eslint-disable prefer-const */ +import { Pool } from '../../types/schema' +import { Flash as FlashEvent } from '../../types/templates/Pool/Pool' + +export function handleFlash(event: FlashEvent): void { + //@TODO: Fill this in and create Flash events. + let pool = Pool.load(event.address.toHexString()) + pool.save() +} diff --git a/src/mappings/core/index.ts b/src/mappings/core/index.ts new file mode 100644 index 00000000..d7595568 --- /dev/null +++ b/src/mappings/core/index.ts @@ -0,0 +1,12 @@ +import { handleInitialize as handleInitializeHelper } from './initialize' +import { handleMint as handleMintHelper } from './mint' +import { handleBurn as handleBurnHelper } from './burn' +import { handleSwap as handleSwapHelper } from './swap' +import { handleFlash as handleFlashHelper } from './flash' +import { handleCollect as handleCollectHelper } from './collect' +export const handleInitialize = handleInitializeHelper +export const handleMint = handleMintHelper +export const handleBurn = handleBurnHelper +export const handleSwap = handleSwapHelper +export const handleFlash = handleFlashHelper +export const handleCollect = handleCollectHelper diff --git a/src/mappings/core/initialize.ts b/src/mappings/core/initialize.ts new file mode 100644 index 00000000..072acc51 --- /dev/null +++ b/src/mappings/core/initialize.ts @@ -0,0 +1,29 @@ +/* eslint-disable prefer-const */ +import { Bundle, Pool, Token } from '../../types/schema' +import { BigInt } from '@graphprotocol/graph-ts' +import { Initialize } from '../../types/templates/Pool/Pool' +import { findEthPerToken, getEthPriceInUSD } from '../../utils/pricing' + +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) + + // Update ETH price now that prices could have changed. + let bundle = Bundle.load('1') + bundle.ethPriceUSD = getEthPriceInUSD() + bundle.save() + + // Update token prices. + token0.derivedETH = findEthPerToken(token0 as Token) + token1.derivedETH = findEthPerToken(token1 as Token) + + // Save entities. + token0.save() + token1.save() + pool.save() +} diff --git a/src/mappings/core/mint.ts b/src/mappings/core/mint.ts new file mode 100644 index 00000000..e946b7ef --- /dev/null +++ b/src/mappings/core/mint.ts @@ -0,0 +1,109 @@ +/* eslint-disable prefer-const */ +import { Bundle, Factory, Mint, Pool, Tick, Token } from '../../types/schema' +import { createTick } from '../../utils/tick' +import { BigInt } from '@graphprotocol/graph-ts' +import { Mint as MintEvent } from '../../types/templates/Pool/Pool' +import { convertTokenToDecimal, loadTransaction } from '../../utils' +import { updateDerivedTVLAmounts } from '../../utils/tvl' +import { + updatePoolDayData, + updatePoolHourData, + updateTokenDayData, + updateTokenHourData, + updateUniswapDayData +} from '../../utils/intervalUpdates' +import { FACTORY_ADDRESS, ONE_BI } from '../../utils/constants' + +export function handleMint(event: MintEvent): void { + let bundle = Bundle.load('1') + let poolAddress = event.address.toHexString() + let pool = Pool.load(poolAddress) + let factory = Factory.load(FACTORY_ADDRESS) + let token0 = Token.load(pool.token0) + let token1 = Token.load(pool.token1) + + // Parse amounts. + let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals) + let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals) + let amountUSD = amount0 + .times(token0.derivedETH.times(bundle.ethPriceUSD)) + .plus(amount1.times(token1.derivedETH.times(bundle.ethPriceUSD))) + + // Transaction count updates. + token0.txCount = token0.txCount.plus(ONE_BI) + token1.txCount = token1.txCount.plus(ONE_BI) + pool.txCount = pool.txCount.plus(ONE_BI) + factory.txCount = factory.txCount.plus(ONE_BI) + + // Update TVL values. + let oldPoolTVLETH = pool.totalValueLockedETH + let oldPoolTVLETHUntracked = pool.totalValueLockedETHUntracked + token0.totalValueLocked = token0.totalValueLocked.plus(amount0) + token1.totalValueLocked = token1.totalValueLocked.plus(amount1) + pool.totalValueLockedToken0 = pool.totalValueLockedToken0.plus(amount0) + pool.totalValueLockedToken1 = pool.totalValueLockedToken1.plus(amount1) + updateDerivedTVLAmounts(pool as Pool, factory as Factory, oldPoolTVLETH, oldPoolTVLETHUntracked) + + // Pools liquidity tracks the currently active liquidity given pools current tick. + // We only want to update it on mint if the new position includes the current tick. + if ( + pool.tick !== null && + BigInt.fromI32(event.params.tickLower).le(pool.tick as BigInt) && + BigInt.fromI32(event.params.tickUpper).gt(pool.tick as BigInt) + ) { + pool.liquidity = pool.liquidity.plus(event.params.amount) + } + + pool.liquidityProviderCount = pool.liquidityProviderCount.plus(ONE_BI) + + let transaction = loadTransaction(event) + let mint = new Mint(transaction.id.toString() + '#' + pool.txCount.toString()) + 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 + mint.amount = event.params.amount + mint.amount0 = amount0 + mint.amount1 = amount1 + mint.amountUSD = amountUSD + mint.tickLower = BigInt.fromI32(event.params.tickLower) + mint.tickUpper = BigInt.fromI32(event.params.tickUpper) + mint.logIndex = event.logIndex + + // Update tick entities. + let lowerTickIdx = event.params.tickLower + let upperTickIdx = event.params.tickUpper + 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) + } + if (upperTick === null) { + upperTick = createTick(upperTickId, upperTickIdx, pool.id, event) + } + let amount = event.params.amount + lowerTick.liquidityGross = lowerTick.liquidityGross.plus(amount) + lowerTick.liquidityNet = lowerTick.liquidityNet.plus(amount) + upperTick.liquidityGross = upperTick.liquidityGross.plus(amount) + upperTick.liquidityNet = upperTick.liquidityNet.minus(amount) + + updateUniswapDayData(event) + updatePoolDayData(event) + updatePoolHourData(event) + updateTokenDayData(token0 as Token, event) + updateTokenDayData(token1 as Token, event) + updateTokenHourData(token0 as Token, event) + updateTokenHourData(token1 as Token, event) + + token0.save() + token1.save() + pool.save() + factory.save() + mint.save() +} diff --git a/src/mappings/core/swap.ts b/src/mappings/core/swap.ts new file mode 100644 index 00000000..5bce84c6 --- /dev/null +++ b/src/mappings/core/swap.ts @@ -0,0 +1,180 @@ +/* eslint-disable prefer-const */ +import { Bundle, Factory, Pool, Swap, Token } from '../../types/schema' +import { BigDecimal, BigInt } from '@graphprotocol/graph-ts' +import { Swap as SwapEvent } from '../../types/templates/Pool/Pool' +import { convertTokenToDecimal, loadTransaction } from '../../utils' +import { FACTORY_ADDRESS, ONE_BI, TWO_BD, ZERO_BD } from '../../utils/constants' +import { + AmountType, + findEthPerToken, + getAdjustedAmounts, + getEthPriceInUSD, + sqrtPriceX96ToTokenPrices +} from '../../utils/pricing' +import { + updatePoolDayData, + updatePoolHourData, + updateTokenDayData, + updateTokenHourData, + updateUniswapDayData +} from '../../utils/intervalUpdates' +import { updateDerivedTVLAmounts } from '../../utils/tvl' + +export function handleSwap(event: SwapEvent): void { + let bundle = Bundle.load('1') + let factory = Factory.load(FACTORY_ADDRESS) + let pool = Pool.load(event.address.toHexString()) + let token0 = Token.load(pool.token0) + let token1 = Token.load(pool.token1) + + // Hot fix for bad pricing. + if (pool.id == '0x9663f2ca0454accad3e094448ea6f77443880454') { + return + } + + // Amounts - 0/1 are token deltas: can be positive or negative. + let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals) + let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals) + + // Calculate volume amounts. Need to divide derived amounts by 2 so volume is not counted on both sides of swap. + let amount0Abs = amount0.times(BigDecimal.fromString(amount0.lt(ZERO_BD) ? '-1' : '1')) + let amount1Abs = amount1.times(BigDecimal.fromString(amount1.lt(ZERO_BD) ? '-1' : '1')) + let volumeAmounts: AmountType = getAdjustedAmounts(amount0Abs, token0 as Token, amount1Abs, token1 as Token) + let volumeETH = volumeAmounts.eth.div(TWO_BD) + let volumeUSD = volumeAmounts.usd.div(TWO_BD) + let volumeUSDUntracked = volumeAmounts.usdUntracked.div(TWO_BD) + + // Fee amounts. + let feesETH = volumeETH.times(pool.feeTier.toBigDecimal()).div(BigDecimal.fromString('1000000')) + let feesUSD = volumeUSD.times(pool.feeTier.toBigDecimal()).div(BigDecimal.fromString('1000000')) + + // Update transaction counts. + factory.txCount = factory.txCount.plus(ONE_BI) + pool.txCount = pool.txCount.plus(ONE_BI) + token0.txCount = token0.txCount.plus(ONE_BI) + token1.txCount = token1.txCount.plus(ONE_BI) + + // Update fees. + factory.feesETH = factory.feesETH.plus(feesETH) + factory.feesUSD = factory.feesUSD.plus(feesUSD) + pool.feesUSD = pool.feesUSD.plus(feesUSD) + token0.feesUSD = token0.feesUSD.plus(feesUSD) + token1.feesUSD = token1.feesUSD.plus(feesUSD) + + // Updates volume. + factory.volumeETH = factory.volumeETH.plus(volumeETH) + factory.volumeUSD = factory.volumeUSD.plus(volumeUSD) + factory.volumeUSDUntracked = factory.volumeUSDUntracked.plus(volumeUSDUntracked) + pool.volumeToken0 = pool.volumeToken0.plus(amount0Abs) + pool.volumeToken1 = pool.volumeToken1.plus(amount1Abs) + pool.volumeUSD = pool.volumeUSD.plus(volumeUSD) + pool.volumeUSDUntracked = pool.volumeUSDUntracked.plus(volumeUSDUntracked) + token0.volume = token0.volume.plus(amount0Abs) + token0.volumeUSD = token0.volumeUSD.plus(volumeUSD) + token0.volumeUSDUntracked = token0.volumeUSDUntracked.plus(volumeUSDUntracked) + token1.volume = token1.volume.plus(amount1Abs) + token1.volumeUSD = token1.volumeUSD.plus(volumeUSD) + token1.volumeUSDUntracked = token1.volumeUSDUntracked.plus(volumeUSDUntracked) + + // Update TVL values. + let oldPoolTVLETH = pool.totalValueLockedETH + let oldPoolTVLETHUntracked = pool.totalValueLockedETHUntracked + pool.totalValueLockedToken0 = pool.totalValueLockedToken0.plus(amount0) + pool.totalValueLockedToken1 = pool.totalValueLockedToken1.plus(amount1) + token0.totalValueLocked = token0.totalValueLocked.plus(amount0) + token1.totalValueLocked = token1.totalValueLocked.plus(amount1) + updateDerivedTVLAmounts(pool as Pool, factory as Factory, oldPoolTVLETH, oldPoolTVLETHUntracked) + + // Update the pool with the new active liquidity, price, and tick. + pool.liquidity = event.params.liquidity + pool.tick = BigInt.fromI32(event.params.tick as i32) + pool.sqrtPrice = event.params.sqrtPriceX96 + + // Update pool specific values + let prices = sqrtPriceX96ToTokenPrices(pool.sqrtPrice, token0 as Token, token1 as Token) + pool.token0Price = prices[0] + pool.token1Price = prices[1] + pool.save() + + // Update USD pricing. + bundle.ethPriceUSD = getEthPriceInUSD() + bundle.save() + token0.derivedETH = findEthPerToken(token0 as Token) + token1.derivedETH = findEthPerToken(token1 as Token) + + // Create Swap event. + let transaction = loadTransaction(event) + let swap = new Swap(transaction.id + '#' + pool.txCount.toString()) + 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 + swap.amount0 = amount0 + swap.amount1 = amount1 + swap.amountUSD = volumeUSD + swap.tick = BigInt.fromI32(event.params.tick as i32) + swap.sqrtPriceX96 = event.params.sqrtPriceX96 + swap.logIndex = event.logIndex + + // Sync inetrval entities with udpated state. + let uniswapDayData = updateUniswapDayData(event) + let poolDayData = updatePoolDayData(event) + let poolHourData = updatePoolHourData(event) + let token0DayData = updateTokenDayData(token0 as Token, event) + let token1DayData = updateTokenDayData(token1 as Token, event) + let token0HourData = updateTokenHourData(token0 as Token, event) + let token1HourData = updateTokenHourData(token1 as Token, event) + + // Add volume updates to interval entities. + uniswapDayData.volumeETH = uniswapDayData.volumeETH.plus(volumeETH) + uniswapDayData.volumeUSD = uniswapDayData.volumeUSD.plus(volumeUSD) + uniswapDayData.feesUSD = uniswapDayData.feesUSD.plus(feesUSD) + + poolDayData.volumeUSD = poolDayData.volumeUSD.plus(volumeUSD) + poolDayData.volumeToken0 = poolDayData.volumeToken0.plus(amount0Abs) + poolDayData.volumeToken1 = poolDayData.volumeToken1.plus(amount1Abs) + poolDayData.feesUSD = poolDayData.feesUSD.plus(feesUSD) + + poolHourData.volumeUSD = poolHourData.volumeUSD.plus(volumeUSD) + poolHourData.volumeToken0 = poolHourData.volumeToken0.plus(amount0Abs) + poolHourData.volumeToken1 = poolHourData.volumeToken1.plus(amount1Abs) + poolHourData.feesUSD = poolHourData.feesUSD.plus(feesUSD) + + token0DayData.volume = token0DayData.volume.plus(amount0Abs) + token0DayData.volumeUSD = token0DayData.volumeUSD.plus(volumeUSD) + token0DayData.volumeUSDUntracked = token0DayData.volumeUSDUntracked.plus(volumeUSDUntracked) + token0DayData.feesUSD = token0DayData.feesUSD.plus(feesUSD) + + token0HourData.volume = token0HourData.volume.plus(amount0Abs) + token0HourData.volumeUSD = token0HourData.volumeUSD.plus(volumeUSD) + token0HourData.volumeUSDUntracked = token0HourData.volumeUSDUntracked.plus(volumeUSDUntracked) + token0HourData.feesUSD = token0HourData.feesUSD.plus(feesUSD) + + token1DayData.volume = token1DayData.volume.plus(amount1Abs) + token1DayData.volumeUSD = token1DayData.volumeUSD.plus(volumeUSD) + token1DayData.volumeUSDUntracked = token1DayData.volumeUSDUntracked.plus(volumeUSDUntracked) + token1DayData.feesUSD = token1DayData.feesUSD.plus(feesUSD) + + token1HourData.volume = token1HourData.volume.plus(amount1Abs) + token1HourData.volumeUSD = token1HourData.volumeUSD.plus(volumeUSD) + token1HourData.volumeUSDUntracked = token1HourData.volumeUSDUntracked.plus(volumeUSDUntracked) + token1HourData.feesUSD = token1HourData.feesUSD.plus(feesUSD) + + // Save entities. + swap.save() + factory.save() + uniswapDayData.save() + pool.save() + poolDayData.save() + poolHourData.save() + token0.save() + token1.save() + token0DayData.save() + token1DayData.save() + token0HourData.save() + token1HourData.save() +} diff --git a/src/mappings/factory.ts b/src/mappings/factory.ts index d8a3ed16..c1bfdcdc 100644 --- a/src/mappings/factory.ts +++ b/src/mappings/factory.ts @@ -1,5 +1,5 @@ -import { WHITELIST_TOKENS } from './../utils/pricing' /* eslint-disable prefer-const */ +import { WHITELIST_TOKENS } from './../utils/pricing' import { FACTORY_ADDRESS, ZERO_BI, ONE_BI, ZERO_BD, ADDRESS_ZERO } from './../utils/constants' import { Factory } from '../types/schema' import { PoolCreated } from '../types/Factory/Factory' @@ -19,11 +19,11 @@ export function handlePoolCreated(event: PoolCreated): void { if (factory === null) { factory = new Factory(FACTORY_ADDRESS) factory.poolCount = ZERO_BI - factory.totalVolumeETH = ZERO_BD - factory.totalVolumeUSD = ZERO_BD - factory.untrackedVolumeUSD = ZERO_BD - factory.totalFeesUSD = ZERO_BD - factory.totalFeesETH = ZERO_BD + factory.volumeETH = ZERO_BD + factory.volumeUSD = ZERO_BD + factory.volumeUSDUntracked = ZERO_BD + factory.feesUSD = ZERO_BD + factory.feesETH = ZERO_BD factory.totalValueLockedETH = ZERO_BD factory.totalValueLockedUSD = ZERO_BD factory.totalValueLockedUSDUntracked = ZERO_BD @@ -61,11 +61,10 @@ export function handlePoolCreated(event: PoolCreated): void { token0.derivedETH = ZERO_BD token0.volume = ZERO_BD token0.volumeUSD = ZERO_BD + token0.volumeUSDUntracked = ZERO_BD token0.feesUSD = ZERO_BD - token0.untrackedVolumeUSD = ZERO_BD token0.totalValueLocked = ZERO_BD token0.totalValueLockedUSD = ZERO_BD - token0.totalValueLockedUSDUntracked = ZERO_BD token0.txCount = ZERO_BI token0.poolCount = ZERO_BI token0.whitelistPools = [] @@ -86,11 +85,10 @@ export function handlePoolCreated(event: PoolCreated): void { token1.derivedETH = ZERO_BD token1.volume = ZERO_BD token1.volumeUSD = ZERO_BD - token1.untrackedVolumeUSD = ZERO_BD + token1.volumeUSDUntracked = ZERO_BD token1.feesUSD = ZERO_BD token1.totalValueLocked = ZERO_BD token1.totalValueLockedUSD = ZERO_BD - token1.totalValueLockedUSDUntracked = ZERO_BD token1.txCount = ZERO_BI token1.poolCount = ZERO_BI token1.whitelistPools = [] @@ -127,12 +125,12 @@ export function handlePoolCreated(event: PoolCreated): void { pool.totalValueLockedUSD = ZERO_BD pool.totalValueLockedETH = ZERO_BD pool.totalValueLockedUSDUntracked = ZERO_BD + pool.totalValueLockedETHUntracked = ZERO_BD pool.volumeToken0 = ZERO_BD pool.volumeToken1 = ZERO_BD pool.volumeUSD = ZERO_BD + pool.volumeUSDUntracked = ZERO_BD pool.feesUSD = ZERO_BD - pool.untrackedVolumeUSD = ZERO_BD - pool.collectedFeesToken0 = ZERO_BD pool.collectedFeesToken1 = ZERO_BD pool.collectedFeesUSD = ZERO_BD diff --git a/src/mappings/position-manager.ts b/src/mappings/position-manager.ts deleted file mode 100644 index c619d646..00000000 --- a/src/mappings/position-manager.ts +++ /dev/null @@ -1,200 +0,0 @@ -/* eslint-disable prefer-const */ -import { - Collect, - DecreaseLiquidity, - IncreaseLiquidity, - NonfungiblePositionManager, - Transfer -} from '../types/NonfungiblePositionManager/NonfungiblePositionManager' -import { Bundle, Position, PositionSnapshot, Token } from '../types/schema' -import { ADDRESS_ZERO, factoryContract, ZERO_BD, ZERO_BI } from '../utils/constants' -import { Address, BigInt, ethereum } from '@graphprotocol/graph-ts' -import { convertTokenToDecimal, loadTransaction } from '../utils' - -function getPosition(event: ethereum.Event, tokenId: BigInt): Position | null { - let position = Position.load(tokenId.toString()) - if (position === null) { - let contract = NonfungiblePositionManager.bind(event.address) - let positionCall = contract.try_positions(tokenId) - - // the following call reverts in situations where the position is minted - // and deleted in the same block - from my investigation this happens - // in calls from BancorSwap - // (e.g. 0xf7867fa19aa65298fadb8d4f72d0daed5e836f3ba01f0b9b9631cdc6c36bed40) - if (!positionCall.reverted) { - let positionResult = positionCall.value - let poolAddress = factoryContract.getPool(positionResult.value2, positionResult.value3, positionResult.value4) - - position = new Position(tokenId.toString()) - // The owner gets correctly updated in the Transfer handler - position.owner = Address.fromString(ADDRESS_ZERO) - position.pool = poolAddress.toHexString() - position.token0 = positionResult.value2.toHexString() - position.token1 = positionResult.value3.toHexString() - position.tickLower = position.pool.concat('#').concat(positionResult.value5.toString()) - position.tickUpper = position.pool.concat('#').concat(positionResult.value6.toString()) - position.liquidity = ZERO_BI - position.depositedToken0 = ZERO_BD - position.depositedToken1 = ZERO_BD - position.withdrawnToken0 = ZERO_BD - position.withdrawnToken1 = ZERO_BD - position.collectedFeesToken0 = ZERO_BD - position.collectedFeesToken1 = ZERO_BD - position.transaction = loadTransaction(event).id - position.feeGrowthInside0LastX128 = positionResult.value8 - position.feeGrowthInside1LastX128 = positionResult.value9 - - position.amountDepositedUSD = ZERO_BD - position.amountWithdrawnUSD = ZERO_BD - position.amountCollectedUSD = ZERO_BD - } - } - - return position -} - -function updateFeeVars(position: Position, event: ethereum.Event, tokenId: BigInt): Position { - let positionManagerContract = NonfungiblePositionManager.bind(event.address) - let positionResult = positionManagerContract.try_positions(tokenId) - if (!positionResult.reverted) { - position.feeGrowthInside0LastX128 = positionResult.value.value8 - position.feeGrowthInside1LastX128 = positionResult.value.value9 - } - return position -} - -function savePositionSnapshot(position: Position, event: ethereum.Event): void { - let positionSnapshot = new PositionSnapshot(position.id.concat('#').concat(event.block.number.toString())) - positionSnapshot.owner = position.owner - positionSnapshot.pool = position.pool - positionSnapshot.position = position.id - positionSnapshot.blockNumber = event.block.number - positionSnapshot.timestamp = event.block.timestamp - positionSnapshot.liquidity = position.liquidity - positionSnapshot.depositedToken0 = position.depositedToken0 - positionSnapshot.depositedToken1 = position.depositedToken1 - positionSnapshot.withdrawnToken0 = position.withdrawnToken0 - positionSnapshot.withdrawnToken1 = position.withdrawnToken1 - positionSnapshot.collectedFeesToken0 = position.collectedFeesToken0 - positionSnapshot.collectedFeesToken1 = position.collectedFeesToken1 - positionSnapshot.transaction = loadTransaction(event).id - positionSnapshot.feeGrowthInside0LastX128 = position.feeGrowthInside0LastX128 - positionSnapshot.feeGrowthInside1LastX128 = position.feeGrowthInside1LastX128 - positionSnapshot.save() -} - -export function handleIncreaseLiquidity(event: IncreaseLiquidity): void { - let position = getPosition(event, event.params.tokenId) - - // position was not able to be fetched - if (position == null) { - return - } - - // temp fix - if (Address.fromString(position.pool).equals(Address.fromHexString('0x8fe8d9bb8eeba3ed688069c3d6b556c9ca258248'))) { - return - } - let bundle = Bundle.load('1') - - let token0 = Token.load(position.token0) - let token1 = Token.load(position.token1) - - let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals) - let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals) - - position.liquidity = position.liquidity.plus(event.params.liquidity) - position.depositedToken0 = position.depositedToken0.plus(amount0) - position.depositedToken1 = position.depositedToken1.plus(amount1) - - let newDepositUSD = amount0 - .times(token0.derivedETH.times(bundle.ethPriceUSD)) - .plus(amount1.times(token1.derivedETH.times(bundle.ethPriceUSD))) - position.amountDepositedUSD = position.amountDepositedUSD.plus(newDepositUSD) - - updateFeeVars(position!, event, event.params.tokenId) - - position.save() - - savePositionSnapshot(position!, event) -} - -export function handleDecreaseLiquidity(event: DecreaseLiquidity): void { - let position = getPosition(event, event.params.tokenId) - - // position was not able to be fetched - if (position == null) { - return - } - - // temp fix - if (Address.fromString(position.pool).equals(Address.fromHexString('0x8fe8d9bb8eeba3ed688069c3d6b556c9ca258248'))) { - return - } - - let bundle = Bundle.load('1') - let token0 = Token.load(position.token0) - let token1 = Token.load(position.token1) - let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals) - let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals) - - position.liquidity = position.liquidity.minus(event.params.liquidity) - position.withdrawnToken0 = position.withdrawnToken0.plus(amount0) - position.withdrawnToken1 = position.withdrawnToken1.plus(amount1) - - let newWithdrawUSD = amount0 - .times(token0.derivedETH.times(bundle.ethPriceUSD)) - .plus(amount1.times(token1.derivedETH.times(bundle.ethPriceUSD))) - position.amountWithdrawnUSD = position.amountWithdrawnUSD.plus(newWithdrawUSD) - - position = updateFeeVars(position!, event, event.params.tokenId) - position.save() - savePositionSnapshot(position!, event) -} - -export function handleCollect(event: Collect): void { - let position = getPosition(event, event.params.tokenId) - // position was not able to be fetched - if (position == null) { - return - } - if (Address.fromString(position.pool).equals(Address.fromHexString('0x8fe8d9bb8eeba3ed688069c3d6b556c9ca258248'))) { - return - } - - - let bundle = Bundle.load('1') - let token0 = Token.load(position.token0) - let token1 = Token.load(position.token1) - let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals) - let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals) - position.collectedToken0 = position.collectedToken0.plus(amount0) - position.collectedToken1 = position.collectedToken1.plus(amount1) - - position.collectedFeesToken0 = position.collectedToken0.minus(position.withdrawnToken0) - position.collectedFeesToken1 = position.collectedToken1.minus(position.withdrawnToken1) - - let newCollectUSD = amount0 - .times(token0.derivedETH.times(bundle.ethPriceUSD)) - .plus(amount1.times(token1.derivedETH.times(bundle.ethPriceUSD))) - position.amountCollectedUSD = position.amountCollectedUSD.plus(newCollectUSD) - - - position = updateFeeVars(position!, event, event.params.tokenId) - position.save() - savePositionSnapshot(position!, event) -} - -export function handleTransfer(event: Transfer): void { - let position = getPosition(event, event.params.tokenId) - - // position was not able to be fetched - if (position == null) { - return - } - - position.owner = event.params.to - position.save() - - savePositionSnapshot(position!, event) -} diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 52a71a92..4eb70e71 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -9,6 +9,7 @@ export let ZERO_BI = BigInt.fromI32(0) export let ONE_BI = BigInt.fromI32(1) export let ZERO_BD = BigDecimal.fromString('0') export let ONE_BD = BigDecimal.fromString('1') +export let TWO_BD = BigDecimal.fromString('2') export let BI_18 = BigInt.fromI32(18) export let factoryContract = FactoryContract.bind(Address.fromString(FACTORY_ADDRESS)) diff --git a/src/utils/intervalUpdates.ts b/src/utils/intervalUpdates.ts index c63cd5ef..225d06a9 100644 --- a/src/utils/intervalUpdates.ts +++ b/src/utils/intervalUpdates.ts @@ -9,9 +9,7 @@ import { TokenDayData, TokenHourData, Bundle, - PoolHourData, - TickDayData, - Tick + PoolHourData } from './../types/schema' import { FACTORY_ADDRESS } from './constants' import { ethereum } from '@graphprotocol/graph-ts' @@ -34,7 +32,7 @@ export function updateUniswapDayData(event: ethereum.Event): UniswapDayData { uniswapDayData.volumeUSDUntracked = ZERO_BD uniswapDayData.feesUSD = ZERO_BD } - uniswapDayData.tvlUSD = uniswap.totalValueLockedUSD + uniswapDayData.totalValueLockedUSD = uniswap.totalValueLockedUSD uniswapDayData.txCount = uniswap.txCount uniswapDayData.save() return uniswapDayData as UniswapDayData @@ -82,7 +80,7 @@ export function updatePoolDayData(event: ethereum.Event): PoolDayData { poolDayData.token0Price = pool.token0Price poolDayData.token1Price = pool.token1Price poolDayData.tick = pool.tick - poolDayData.tvlUSD = pool.totalValueLockedUSD + poolDayData.totalValueLockedUSD = pool.totalValueLockedUSD poolDayData.txCount = poolDayData.txCount.plus(ONE_BI) poolDayData.save() @@ -132,7 +130,7 @@ export function updatePoolHourData(event: ethereum.Event): PoolHourData { poolHourData.feeGrowthGlobal1X128 = pool.feeGrowthGlobal1X128 poolHourData.close = pool.token0Price poolHourData.tick = pool.tick - poolHourData.tvlUSD = pool.totalValueLockedUSD + poolHourData.totalValueLockedUSD = pool.totalValueLockedUSD poolHourData.txCount = poolHourData.txCount.plus(ONE_BI) poolHourData.save() @@ -159,7 +157,7 @@ export function updateTokenDayData(token: Token, event: ethereum.Event): TokenDa tokenDayData.volume = ZERO_BD tokenDayData.volumeUSD = ZERO_BD tokenDayData.feesUSD = ZERO_BD - tokenDayData.untrackedVolumeUSD = ZERO_BD + tokenDayData.volumeUSDUntracked = ZERO_BD tokenDayData.open = tokenPrice tokenDayData.high = tokenPrice tokenDayData.low = tokenPrice @@ -201,7 +199,7 @@ export function updateTokenHourData(token: Token, event: ethereum.Event): TokenH tokenHourData.token = token.id tokenHourData.volume = ZERO_BD tokenHourData.volumeUSD = ZERO_BD - tokenHourData.untrackedVolumeUSD = ZERO_BD + tokenHourData.volumeUSDUntracked = ZERO_BD tokenHourData.feesUSD = ZERO_BD tokenHourData.open = tokenPrice tokenHourData.high = tokenPrice @@ -225,29 +223,3 @@ export function updateTokenHourData(token: Token, event: ethereum.Event): TokenH return tokenHourData as TokenHourData } - -export function updateTickDayData(tick: Tick, event: ethereum.Event): TickDayData { - let timestamp = event.block.timestamp.toI32() - let dayID = timestamp / 86400 - let dayStartTimestamp = dayID * 86400 - let tickDayDataID = tick.id.concat('-').concat(dayID.toString()) - let tickDayData = TickDayData.load(tickDayDataID) - if (tickDayData === null) { - tickDayData = new TickDayData(tickDayDataID) - tickDayData.date = dayStartTimestamp - tickDayData.pool = tick.pool - tickDayData.tick = tick.id - } - tickDayData.liquidityGross = tick.liquidityGross - tickDayData.liquidityNet = tick.liquidityNet - tickDayData.volumeToken0 = tick.volumeToken0 - tickDayData.volumeToken1 = tick.volumeToken0 - tickDayData.volumeUSD = tick.volumeUSD - tickDayData.feesUSD = tick.feesUSD - tickDayData.feeGrowthOutside0X128 = tick.feeGrowthOutside0X128 - tickDayData.feeGrowthOutside1X128 = tick.feeGrowthOutside1X128 - - tickDayData.save() - - return tickDayData as TickDayData -} diff --git a/src/utils/pricing.ts b/src/utils/pricing.ts index a4e0bca4..ed9f4062 100644 --- a/src/utils/pricing.ts +++ b/src/utils/pricing.ts @@ -42,7 +42,7 @@ let STABLE_COINS: string[] = [ '0x4dd28568d05f09b02220b09c2cb307bfd837cb95' ] -let MINIMUM_ETH_LOCKED = BigDecimal.fromString('52') +let MINIMUM_ETH_LOCKED = BigDecimal.fromString('60') let Q192 = 2 ** 192 export function sqrtPriceX96ToTokenPrices(sqrtPriceX96: BigInt, token0: Token, token1: Token): BigDecimal[] { @@ -97,7 +97,10 @@ export function findEthPerToken(token: Token): BigDecimal { let token1 = Token.load(pool.token1) // get the derived ETH in pool let ethLocked = pool.totalValueLockedToken1.times(token1.derivedETH) - if (ethLocked.gt(largestLiquidityETH) && ethLocked.gt(MINIMUM_ETH_LOCKED)) { + if ( + ethLocked.gt(largestLiquidityETH) && + (ethLocked.gt(MINIMUM_ETH_LOCKED) || WHITELIST_TOKENS.includes(pool.token0)) + ) { largestLiquidityETH = ethLocked // token1 per our token * Eth per token1 priceSoFar = pool.token1Price.times(token1.derivedETH as BigDecimal) @@ -107,7 +110,10 @@ export function findEthPerToken(token: Token): BigDecimal { let token0 = Token.load(pool.token0) // get the derived ETH in pool let ethLocked = pool.totalValueLockedToken0.times(token0.derivedETH) - if (ethLocked.gt(largestLiquidityETH) && ethLocked.gt(MINIMUM_ETH_LOCKED)) { + if ( + ethLocked.gt(largestLiquidityETH) && + (ethLocked.gt(MINIMUM_ETH_LOCKED) || WHITELIST_TOKENS.includes(pool.token1)) + ) { largestLiquidityETH = ethLocked // token0 per our token * ETH per token0 priceSoFar = pool.token0Price.times(token0.derivedETH as BigDecimal) @@ -153,3 +159,79 @@ export function getTrackedAmountUSD( // neither token is on white list, tracked amount 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. + * If both are, return sum of two amounts + * If neither is, return 0 + */ +export function getTrackedAmountETH( + tokenAmount0: BigDecimal, + token0: Token, + tokenAmount1: BigDecimal, + token1: Token +): BigDecimal { + let derivedETH0 = token0.derivedETH + let derivedETH1 = token1.derivedETH + + // both are whitelist tokens, return sum of both amounts + if (WHITELIST_TOKENS.includes(token0.id) && WHITELIST_TOKENS.includes(token1.id)) { + return tokenAmount0.times(derivedETH0).plus(tokenAmount1.times(derivedETH1)) + } + + // take double value of the whitelisted token amount + if (WHITELIST_TOKENS.includes(token0.id) && !WHITELIST_TOKENS.includes(token1.id)) { + return tokenAmount0.times(derivedETH0).times(BigDecimal.fromString('2')) + } + + // take double value of the whitelisted token amount + if (!WHITELIST_TOKENS.includes(token0.id) && WHITELIST_TOKENS.includes(token1.id)) { + return tokenAmount1.times(derivedETH1).times(BigDecimal.fromString('2')) + } + + // neither token is on white list, tracked amount is 0 + return ZERO_BD +} + +export class AmountType { + eth: BigDecimal + usd: BigDecimal + ethUntracked: BigDecimal + usdUntracked: BigDecimal +} + +export function getAdjustedAmounts( + tokenAmount0: BigDecimal, + token0: Token, + tokenAmount1: BigDecimal, + token1: Token +): AmountType { + let derivedETH0 = token0.derivedETH + let derivedETH1 = token1.derivedETH + let bundle = Bundle.load('1') + + let eth = ZERO_BD + let ethUntracked = tokenAmount0.times(derivedETH0).plus(tokenAmount1.times(derivedETH1)) + + // both are whitelist tokens, return sum of both amounts + if (WHITELIST_TOKENS.includes(token0.id) && WHITELIST_TOKENS.includes(token1.id)) { + eth = ethUntracked + } + + // take double value of the whitelisted token amount + if (WHITELIST_TOKENS.includes(token0.id) && !WHITELIST_TOKENS.includes(token1.id)) { + eth = tokenAmount0.times(derivedETH0).times(BigDecimal.fromString('2')) + } + + // take double value of the whitelisted token amount + if (!WHITELIST_TOKENS.includes(token0.id) && WHITELIST_TOKENS.includes(token1.id)) { + eth = tokenAmount1.times(derivedETH1).times(BigDecimal.fromString('2')) + } + + // Define USD values based on ETH derived values. + let usd = eth.times(bundle.ethPriceUSD) + let usdUntracked = ethUntracked.times(bundle.ethPriceUSD) + + return { eth, usd, ethUntracked, usdUntracked } +} diff --git a/src/utils/tick.ts b/src/utils/tick.ts index c206a2c2..53a25a18 100644 --- a/src/utils/tick.ts +++ b/src/utils/tick.ts @@ -3,7 +3,7 @@ import { BigDecimal, BigInt } from '@graphprotocol/graph-ts' import { bigDecimalExponated, safeDiv } from '.' import { Tick } from '../types/schema' import { Mint as MintEvent } from '../types/templates/Pool/Pool' -import { ONE_BD, ZERO_BD, ZERO_BI } from './constants' +import { ONE_BD, ZERO_BI } from './constants' export function createTick(tickId: string, tickIdx: i32, poolId: string, event: MintEvent): Tick { let tick = new Tick(tickId) @@ -15,7 +15,6 @@ export function createTick(tickId: string, tickIdx: i32, poolId: string, event: tick.createdAtBlockNumber = event.block.number tick.liquidityGross = ZERO_BI tick.liquidityNet = ZERO_BI - tick.liquidityProviderCount = ZERO_BI tick.price0 = ONE_BD tick.price1 = ONE_BD @@ -25,18 +24,6 @@ export function createTick(tickId: string, tickIdx: i32, poolId: string, event: tick.price0 = price0 tick.price1 = safeDiv(ONE_BD, price0) - tick.volumeToken0 = ZERO_BD - tick.volumeToken1 = ZERO_BD - tick.volumeUSD = ZERO_BD - tick.feesUSD = ZERO_BD - tick.untrackedVolumeUSD = ZERO_BD - tick.collectedFeesToken0 = ZERO_BD - tick.collectedFeesToken1 = ZERO_BD - tick.collectedFeesUSD = ZERO_BD - tick.liquidityProviderCount = ZERO_BI - tick.feeGrowthOutside0X128 = ZERO_BI - tick.feeGrowthOutside1X128 = ZERO_BI - return tick } diff --git a/src/utils/tvl.ts b/src/utils/tvl.ts new file mode 100644 index 00000000..9ec7aea1 --- /dev/null +++ b/src/utils/tvl.ts @@ -0,0 +1,68 @@ +/* eslint-disable prefer-const */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { BigDecimal } from '@graphprotocol/graph-ts' +import { Bundle, Factory, Pool, Token } from '../types/schema' +import { AmountType, getAdjustedAmounts } from './pricing' + +/** + * Updates all dervived TVL values. This includes all ETH and USD + * TVL metrics for a given pool, as well as in the aggregate factory. + * + * NOTE: tokens locked should be updated before this function is called, + * as this logic starts its calculations based on TVL for token0 and token1 + * in the pool. + * + * This function should be used whenever the TVL of tokens changes within a pool. + * Aka: mint, burn, swap, collect + * + * @param pool + * @param factory + * @param oldPoolTotalValueLockedETH + */ +export function updateDerivedTVLAmounts( + pool: Pool, + factory: Factory, + oldPoolTotalValueLockedETH: BigDecimal, + oldPoolTotalValueLockedETHUntracked: BigDecimal +): void { + let bundle = Bundle.load('1') + let token0 = Token.load(pool.token0) + let token1 = Token.load(pool.token1) + + // Update token TVL values. + token0.totalValueLockedUSD = token0.totalValueLocked.times(token0.derivedETH.times(bundle.ethPriceUSD)) + token1.totalValueLockedUSD = token1.totalValueLocked.times(token1.derivedETH.times(bundle.ethPriceUSD)) + + // Get tracked and untracked amounts based on tokens in pool. + let amounts: AmountType = getAdjustedAmounts( + pool.totalValueLockedToken0, + token0 as Token, + pool.totalValueLockedToken1, + token1 as Token + ) + + // Update pool TVL values. + pool.totalValueLockedETH = amounts.eth + pool.totalValueLockedUSD = amounts.usd + pool.totalValueLockedETHUntracked = amounts.ethUntracked + pool.totalValueLockedUSDUntracked = amounts.usdUntracked + + /** + * ----- RESET ------ + * We need to reset factory values before updating with new amounts. + */ + factory.totalValueLockedETH = factory.totalValueLockedETH.minus(oldPoolTotalValueLockedETH) + factory.totalValueLockedETHUntracked = factory.totalValueLockedETHUntracked.minus(oldPoolTotalValueLockedETHUntracked) + + // Add new TVL based on pool. + factory.totalValueLockedETH = factory.totalValueLockedETH.plus(amounts.eth) + factory.totalValueLockedETHUntracked = factory.totalValueLockedETHUntracked.plus(amounts.ethUntracked) + factory.totalValueLockedUSD = factory.totalValueLockedETH.times(bundle.ethPriceUSD) + factory.totalValueLockedUSDUntracked = factory.totalValueLockedETHUntracked.times(bundle.ethPriceUSD) + + // Save entities. + token0.save() + token1.save() + factory.save() + pool.save() +} diff --git a/subgraph.yaml b/subgraph.yaml index 03459143..5595276f 100644 --- a/subgraph.yaml +++ b/subgraph.yaml @@ -3,9 +3,9 @@ description: Uniswap is a decentralized protocol for automated token exchange on repository: https://github.com/Uniswap/uniswap-v3-subgraph schema: file: ./schema.graphql -graft: - base: QmZeCuoZeadgHkGwLwMeguyqUKz1WPWQYKcKyMCeQqGhsF - block: 12673736 +# graft: +# base: QmPrb5mvZj3ycUugZgwLWCvK93jfXfhvfjRXrFk4tRmyCX +# block: 14317965 dataSources: - kind: ethereum/contract name: Factory @@ -36,39 +36,6 @@ dataSources: eventHandlers: - event: PoolCreated(indexed address,indexed address,indexed uint24,int24,address) handler: handlePoolCreated - - kind: ethereum/contract - name: NonfungiblePositionManager - network: mainnet - source: - address: '0xC36442b4a4522E871399CD717aBDD847Ab11FE88' - abi: NonfungiblePositionManager - startBlock: 12369651 - mapping: - kind: ethereum/events - apiVersion: 0.0.4 - language: wasm/assemblyscript - file: ./src/mappings/position-manager.ts - entities: - - Pool - - Token - abis: - - name: NonfungiblePositionManager - file: ./abis/NonfungiblePositionManager.json - - name: Pool - file: ./abis/pool.json - - name: Factory - file: ./abis/factory.json - - name: ERC20 - file: ./abis/ERC20.json - eventHandlers: - - event: IncreaseLiquidity(indexed uint256,uint128,uint256,uint256) - handler: handleIncreaseLiquidity - - event: DecreaseLiquidity(indexed uint256,uint128,uint256,uint256) - handler: handleDecreaseLiquidity - - event: Collect(indexed uint256,address,uint256,uint256) - handler: handleCollect - - event: Transfer(indexed address,indexed address,indexed uint256) - handler: handleTransfer templates: - kind: ethereum/contract name: Pool @@ -79,7 +46,7 @@ templates: kind: ethereum/events apiVersion: 0.0.4 language: wasm/assemblyscript - file: ./src/mappings/core.ts + file: ./src/mappings/core/index.ts entities: - Pool - Token diff --git a/yarn.lock b/yarn.lock index 583865c2..ea76c05c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,10 +23,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@graphprotocol/graph-cli@0.21.1": - version "0.21.1" - resolved "https://registry.yarnpkg.com/@graphprotocol/graph-cli/-/graph-cli-0.21.1.tgz#06cc85f3b950c01ca12c87c1fa47cacf4deec078" - integrity sha512-bqHlHZTzfEJICUpGQQr4Pru07OiGiOpIiwkVSdQMJaiuwu+bflMmLJNYNbSRH2byqaWDZvc4MI3U9CwUYXdRRw== +"@graphprotocol/graph-cli@^0.20.0": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@graphprotocol/graph-cli/-/graph-cli-0.20.1.tgz#659459091821861987e6596b46e692ca4a3c2b3b" + integrity sha512-vT8pKz2OMyLcYGiFK8RVUk0HHYT9hYYdGwlYAOUON3HHIr51EjSbvTHW7ezBfneFurzj9z0Xdezwywf/N1ay0Q== dependencies: assemblyscript "git+https://github.com/AssemblyScript/assemblyscript.git#v0.6" chalk "^3.0.0" @@ -46,15 +46,17 @@ pkginfo "^0.4.1" prettier "^1.13.5" request "^2.88.0" - tmp-promise "^3.0.2" + tmp "^0.1.0" yaml "^1.5.1" + optionalDependencies: + keytar "^7.4.0" -"@graphprotocol/graph-ts@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.20.0.tgz#ed31ffd59a6aa9703a1ec5079f137a81220443cb" - integrity sha512-+R0Tu/MD4Fiq0Fo+v1l+xznz+ZrciQKWlzMtXjDrhM70vlMNVL9wDmf90MVFYpslgqIfw024hT6XwlmyNyOWbQ== +"@graphprotocol/graph-ts@^0.20.0": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.20.1.tgz#42a45158c5904224f28d3cf6c5d1ffc876720f81" + integrity sha512-JATb0tERXt+JZUYuW9rwfnLzIM4EOBHf/EEZir5JMiIVMP55CoOyQGAwH2dvKSm5O8WQ1BfdbnOvk7YNVMFHsg== dependencies: - assemblyscript "https://github.com/AssemblyScript/assemblyscript#36040d5b5312f19a025782b5e36663823494c2f3" + assemblyscript "git+https://github.com/AssemblyScript/assemblyscript.git#v0.6" "@protobufjs/utf8@^1.1.0": version "1.1.0" @@ -215,6 +217,11 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.21.3" +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" @@ -230,6 +237,11 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -265,6 +277,19 @@ app-module-path@^2.2.0: resolved "https://registry.yarnpkg.com/app-module-path/-/app-module-path-2.2.0.tgz#641aa55dfb7d6a6f0a8141c4b9c0aa50b6c24dd5" integrity sha1-ZBqlXft9am8KgUHEucCqULbCTdU= +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.7" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" + integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -294,17 +319,6 @@ asn1@~0.2.3: dependencies: safer-buffer "~2.1.0" -"assemblyscript@git+https://github.com/AssemblyScript/assemblyscript.git#36040d5b5312f19a025782b5e36663823494c2f3": - version "0.6.0" - resolved "git+https://github.com/AssemblyScript/assemblyscript.git#36040d5b5312f19a025782b5e36663823494c2f3" - dependencies: - "@protobufjs/utf8" "^1.1.0" - binaryen "77.0.0-nightly.20190407" - glob "^7.1.3" - long "^4.0.0" - opencollective-postinstall "^2.0.0" - source-map-support "^0.5.11" - "assemblyscript@git+https://github.com/AssemblyScript/assemblyscript.git#v0.6": version "0.6.0" resolved "git+https://github.com/AssemblyScript/assemblyscript.git#3ed76a97f05335504166fce1653da75f4face28f" @@ -616,7 +630,7 @@ chokidar@^3.0.2: optionalDependencies: fsevents "~2.3.1" -chownr@^1.0.1: +chownr@^1.0.1, chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== @@ -688,6 +702,11 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -751,6 +770,11 @@ concat-stream@~1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -836,6 +860,18 @@ decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -853,11 +889,21 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + delimit-stream@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/delimit-stream/-/delimit-stream-0.1.0.tgz#9b8319477c0e5f8aeb3ce357ae305fc25ea1cd2b" integrity sha1-m4MZR3wOX4rrPONXrjBfwl6hzSs= +detect-libc@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" + integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== + detect-node@^2.0.4: version "2.0.5" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.5.tgz#9d270aa7eaa5af0b72c4c9d9b814e7f4ce738b79" @@ -1138,6 +1184,11 @@ execa@^3.0.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + explain-error@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/explain-error/-/explain-error-1.0.4.tgz#a793d3ac0cad4c6ab571e9968fbbab6cb2532929" @@ -1294,6 +1345,20 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + get-intrinsic@^1.0.2: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" @@ -1322,6 +1387,11 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + glob-parent@^5.0.0, glob-parent@~5.1.0: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -1423,6 +1493,11 @@ has-symbols@^1.0.1: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -1523,6 +1598,11 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + inquirer@^7.0.0: version "7.3.3" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" @@ -1700,6 +1780,13 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -1933,6 +2020,14 @@ keypair@^1.0.1: resolved "https://registry.yarnpkg.com/keypair/-/keypair-1.0.3.tgz#4314109d94052a0acfd6b885695026ad29529c80" integrity sha512-0wjZ2z/SfZZq01+3/8jYLd8aEShSa+aat1zyPGQY3IuKoEAp6DJGvu2zt6snELrQU9jbCkIlCyNOD7RdQbHhkQ== +keytar@^7.4.0: + version "7.9.0" + resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.9.0.tgz#4c6225708f51b50cbf77c5aae81721964c2918cb" + integrity sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ== + dependencies: + node-addon-api "^4.3.0" + prebuild-install "^7.0.1" + kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" @@ -2154,6 +2249,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -2171,11 +2271,16 @@ minimatch@^3.0.2, minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.5: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + mkdirp@^0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -2340,6 +2445,11 @@ nan@^2.14.0, nan@^2.14.2: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -2359,6 +2469,18 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-abi@^3.3.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.8.0.tgz#679957dc8e7aa47b0a02589dbfde4f77b29ccb32" + integrity sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw== + dependencies: + semver "^7.3.5" + +node-addon-api@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" + integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== + node-fetch@^2.3.0: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" @@ -2389,6 +2511,21 @@ npm-run-path@^4.0.0: dependencies: path-key "^3.0.0" +npmlog@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -2555,6 +2692,25 @@ pluralize@^8.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== +prebuild-install@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.1.tgz#c10075727c318efe72412f333e0ef625beaf3870" + integrity sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -2679,6 +2835,16 @@ ramdasauce@^2.1.0: dependencies: ramda "^0.24.1" +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + "readable-stream@2 || 3", readable-stream@^3.0.0, readable-stream@^3.0.1, readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" @@ -2688,7 +2854,7 @@ ramdasauce@^2.1.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5: +readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -2781,13 +2947,6 @@ rimraf@^2.6.3: dependencies: glob "^7.1.3" -rimraf@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -2862,13 +3021,18 @@ semver@^6.1.2: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.0.0, semver@^7.3.2: +semver@^7.0.0, semver@^7.3.2, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== dependencies: lru-cache "^6.0.0" +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.11" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" @@ -2910,6 +3074,11 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +signal-exit@^3.0.0: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" @@ -2922,6 +3091,20 @@ signed-varint@^2.0.1: dependencies: varint "~5.0.0" +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + slice-ansi@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" @@ -2989,6 +3172,24 @@ stream-to-pull-stream@^1.7.2: looper "^3.0.0" pull-stream "^3.2.3" +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2 || 3 || 4": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" @@ -3034,6 +3235,13 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -3055,6 +3263,13 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" @@ -3065,6 +3280,11 @@ strip-json-comments@^3.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -3089,6 +3309,16 @@ table@^5.2.3: slice-ansi "^2.1.0" string-width "^3.0.0" +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + tar-fs@~1.16.3: version "1.16.3" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509" @@ -3112,7 +3342,7 @@ tar-stream@^1.1.2: to-buffer "^1.1.1" xtend "^4.0.0" -tar-stream@^2.0.1: +tar-stream@^2.0.1, tar-stream@^2.1.4: version "2.2.0" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== @@ -3141,13 +3371,6 @@ through2@^3.0.0, through2@^3.0.1: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -tmp-promise@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.2.tgz#6e933782abff8b00c3119d63589ca1fb9caaa62a" - integrity sha512-OyCLAKU1HzBjL6Ev3gxUeraJNlbNingmi8IrHHEsYH8LTmEuhvYfqvhn2F/je+mjf4N58UmZ96OMEy1JanSCpA== - dependencies: - tmp "^0.2.0" - tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -3155,12 +3378,12 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -tmp@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== +tmp@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" + integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== dependencies: - rimraf "^3.0.0" + rimraf "^2.6.3" to-buffer@^1.1.1: version "1.1.1" @@ -3313,6 +3536,13 @@ which@^2.0.0, which@^2.0.1: dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" From 48c38ce9a3a38e72958381c2bf3dd0a3ec76b464 Mon Sep 17 00:00:00 2001 From: ianlapham Date: Fri, 11 Mar 2022 12:56:40 -0500 Subject: [PATCH 4/7] fix export style in index --- src/mappings/core/index.ts | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/mappings/core/index.ts b/src/mappings/core/index.ts index d7595568..5bf5effd 100644 --- a/src/mappings/core/index.ts +++ b/src/mappings/core/index.ts @@ -2,11 +2,26 @@ import { handleInitialize as handleInitializeHelper } from './initialize' import { handleMint as handleMintHelper } from './mint' import { handleBurn as handleBurnHelper } from './burn' import { handleSwap as handleSwapHelper } from './swap' -import { handleFlash as handleFlashHelper } from './flash' import { handleCollect as handleCollectHelper } from './collect' -export const handleInitialize = handleInitializeHelper -export const handleMint = handleMintHelper -export const handleBurn = handleBurnHelper -export const handleSwap = handleSwapHelper -export const handleFlash = handleFlashHelper -export const handleCollect = handleCollectHelper +import { handleFlash as handleFlashHelper } from './flash' +import { Initialize, Mint, Burn, Swap, Collect, Flash } from '../../types/templates/Pool/Pool' + +// Workaround for limited export types in Assemblyscript. +export function handleInitialize(event: Initialize): void { + handleInitializeHelper(event) +} +export function handleMint(event: Mint): void { + handleMintHelper(event) +} +export function handleBurn(event: Burn): void { + handleBurnHelper(event) +} +export function handleSwap(event: Swap): void { + handleSwapHelper(event) +} +export function handleCollect(event: Collect): void { + handleCollectHelper(event) +} +export function handleFlash(event: Flash): void { + handleFlashHelper(event) +} From acf78023b902adb6cc9fb5c75836e4e732f70f68 Mon Sep 17 00:00:00 2001 From: ianlapham Date: Sun, 13 Mar 2022 17:28:03 -0400 Subject: [PATCH 5/7] update comments --- src/mappings/core/mint.ts | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/mappings/core/mint.ts b/src/mappings/core/mint.ts index e946b7ef..92e94e44 100644 --- a/src/mappings/core/mint.ts +++ b/src/mappings/core/mint.ts @@ -1,6 +1,5 @@ /* eslint-disable prefer-const */ -import { Bundle, Factory, Mint, Pool, Tick, Token } from '../../types/schema' -import { createTick } from '../../utils/tick' +import { Bundle, Factory, Mint, Pool, Token } from '../../types/schema' import { BigInt } from '@graphprotocol/graph-ts' import { Mint as MintEvent } from '../../types/templates/Pool/Pool' import { convertTokenToDecimal, loadTransaction } from '../../utils' @@ -74,25 +73,6 @@ export function handleMint(event: MintEvent): void { mint.tickUpper = BigInt.fromI32(event.params.tickUpper) mint.logIndex = event.logIndex - // Update tick entities. - let lowerTickIdx = event.params.tickLower - let upperTickIdx = event.params.tickUpper - 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) - } - if (upperTick === null) { - upperTick = createTick(upperTickId, upperTickIdx, pool.id, event) - } - let amount = event.params.amount - lowerTick.liquidityGross = lowerTick.liquidityGross.plus(amount) - lowerTick.liquidityNet = lowerTick.liquidityNet.plus(amount) - upperTick.liquidityGross = upperTick.liquidityGross.plus(amount) - upperTick.liquidityNet = upperTick.liquidityNet.minus(amount) - updateUniswapDayData(event) updatePoolDayData(event) updatePoolHourData(event) From 9fdeadf4b2625cb7052ab08e7982ea093ce21805 Mon Sep 17 00:00:00 2001 From: ianlapham Date: Sun, 13 Mar 2022 17:49:19 -0400 Subject: [PATCH 6/7] update TVL after prices and token TVL is updated --- src/mappings/core/swap.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/mappings/core/swap.ts b/src/mappings/core/swap.ts index 5bce84c6..0033c89b 100644 --- a/src/mappings/core/swap.ts +++ b/src/mappings/core/swap.ts @@ -76,15 +76,6 @@ export function handleSwap(event: SwapEvent): void { token1.volumeUSD = token1.volumeUSD.plus(volumeUSD) token1.volumeUSDUntracked = token1.volumeUSDUntracked.plus(volumeUSDUntracked) - // Update TVL values. - let oldPoolTVLETH = pool.totalValueLockedETH - let oldPoolTVLETHUntracked = pool.totalValueLockedETHUntracked - pool.totalValueLockedToken0 = pool.totalValueLockedToken0.plus(amount0) - pool.totalValueLockedToken1 = pool.totalValueLockedToken1.plus(amount1) - token0.totalValueLocked = token0.totalValueLocked.plus(amount0) - token1.totalValueLocked = token1.totalValueLocked.plus(amount1) - updateDerivedTVLAmounts(pool as Pool, factory as Factory, oldPoolTVLETH, oldPoolTVLETHUntracked) - // Update the pool with the new active liquidity, price, and tick. pool.liquidity = event.params.liquidity pool.tick = BigInt.fromI32(event.params.tick as i32) @@ -102,6 +93,15 @@ export function handleSwap(event: SwapEvent): void { token0.derivedETH = findEthPerToken(token0 as Token) token1.derivedETH = findEthPerToken(token1 as Token) + // Update TVL values. + let oldPoolTVLETH = pool.totalValueLockedETH + let oldPoolTVLETHUntracked = pool.totalValueLockedETHUntracked + pool.totalValueLockedToken0 = pool.totalValueLockedToken0.plus(amount0) + pool.totalValueLockedToken1 = pool.totalValueLockedToken1.plus(amount1) + token0.totalValueLocked = token0.totalValueLocked.plus(amount0) + token1.totalValueLocked = token1.totalValueLocked.plus(amount1) + updateDerivedTVLAmounts(pool as Pool, factory as Factory, oldPoolTVLETH, oldPoolTVLETHUntracked) + // Create Swap event. let transaction = loadTransaction(event) let swap = new Swap(transaction.id + '#' + pool.txCount.toString()) From 8bc4b9c6cf1464136898c17209a2049d7ef8d673 Mon Sep 17 00:00:00 2001 From: Ian Lapham Date: Wed, 28 Sep 2022 11:43:59 -0400 Subject: [PATCH 7/7] Update README.md --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3cde004d..45d04958 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,12 @@ # Uniswap V3 Subgraph +This code is an updated, more accurate, version of the original v3 subgraph. This code fixes issues in TVL, collect events, and more. + +The main difference is that this subgraph does not track data related to positions. The reason is that to track position data accurately, we need to use multiple `eth_calls` within the subgraph mappings - `eth_calls` consume about 60-80% of sync time in the original subgraph. Without these, the subgrpah can be synced in a matter of weeks as opposed to a matter of months. + +More documentation will be coming soon. + ### Subgraph Endpoint -Synced at: https://thegraph.com/hosted-service/subgraph/ianlapham/uniswap-v3-subgraph?selected=playground +Synced at: https://thegraph.com/hosted-service/subgraph/ianlapham/v3-minimal -Pending Changes at same URL