Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,4 @@
**/types/
.DS_STORE
yarn-error.log
.env

# subgraph.yaml should be compiled before deploy
subgraph.yaml
.env
16 changes: 2 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ Make any additions or changes to the `subgraph.yaml` file to include contracts a

Ensure that any entity declarations and ABIs referenced exist and are defined well. The `schema.graphql` file contains all object structures queryable through the graph.

### Configure networks

Populate the `networks.json` file with the contracts for each network that you are defining subgraphs for.

### Generate types

```
Expand All @@ -33,19 +29,11 @@ yarn codegen
### Compile subgraph

```
yarn build --network <network>
yarn build
```

### Deploy subgraph

For production:

```
yarn deploy:mainnet
```

For testnet:

```
yarn deploy:optimism-goerli
yarn deploy
```
22 changes: 0 additions & 22 deletions networks.json

This file was deleted.

9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@
"build": "graph build",
"create-local": "graph create violetprotocol/mauve-subgraph --node http://127.0.0.1:8020",
"deploy-local": "graph deploy violetprotocol/mauve-subgraph --debug --ipfs http://localhost:5001 --node http://127.0.0.1:8020",
"deploy:mainnet": "source .env && graph deploy violetprotocol/mauve-subgraph --access-token $ACCESS_TOKEN --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/ --debug --network mainnet",
"deploy:optimism-goerli": "source .env && graph deploy violetprotocol/phlox-subgraph --access-token $ACCESS_TOKEN --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/ --debug --network optimism-goerli",
"deploy": "source .env && graph deploy violetprotocol/mauve-subgraph --access-token $ACCESS_TOKEN --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/ --debug",
"deploy-dev": "graph deploy violetprotocol/mauve-subgraph --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 /mauve --ipfs https://api.staging.thegraph.com/ipfs/ --node https://api.staging.thegraph.com/deploy/",
"deploy-staging": "graph deploy $THE_GRAPH_GITHUB_USER/$THE_GRAPH_SUBGRAPH_NAME /Mauve --ipfs https://api.staging.thegraph.com/ipfs/ --node https://api.staging.thegraph.com/deploy/",
"watch-local": "graph deploy violetprotocol/mauve-subgraph --watch --debug --node http://127.0.0.1:8020/ --ipfs http://localhost:5001"
},
"devDependencies": {
"@graphprotocol/graph-cli": "0.32.0",
"@graphprotocol/graph-ts": "0.25.0",
"@graphprotocol/graph-cli": "^0.20.0",
"@graphprotocol/graph-ts": "^0.20.0",
"@typescript-eslint/eslint-plugin": "^2.0.0",
"@typescript-eslint/parser": "^2.0.0",
"eslint": "^6.2.2",
Expand Down
87 changes: 31 additions & 56 deletions src/mappings/core.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* 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, dataSource, ethereum } from '@graphprotocol/graph-ts'
import { BigDecimal, BigInt, ethereum } from '@graphprotocol/graph-ts'
import {
Burn as BurnEvent,
Flash as FlashEvent,
Expand All @@ -10,7 +10,7 @@ import {
Swap as SwapEvent
} from '../types/templates/Pool/Pool'
import { convertTokenToDecimal, loadTransaction, safeDiv } from '../utils'
import { FACTORY_ADDRESSES, ONE_BI, ZERO_BD, ZERO_BI } from '../utils/constants'
import { FACTORY_ADDRESS, ONE_BI, ZERO_BD, ZERO_BI } from '../utils/constants'
import { findEthPerToken, getEthPriceInUSD, getTrackedAmountUSD, sqrtPriceX96ToTokenPrices } from '../utils/pricing'
import {
updatePoolDayData,
Expand All @@ -22,54 +22,26 @@ import {
} from '../utils/intervalUpdates'
import { createTick, feeTierToTickSpacing } from '../utils/tick'

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)
}
}

export function handleInitialize(event: Initialize): void {
// update pool sqrt price and tick
let pool = Pool.load(event.address.toHexString())
if (!pool) return
pool.sqrtPrice = event.params.sqrtPriceX96
pool.tick = BigInt.fromI32(event.params.tick)
pool.save()

// 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')
if (!bundle) return
bundle.ethPriceUSD = getEthPriceInUSD()
bundle.save()

updatePoolDayData(event)
updatePoolHourData(event)

// update token prices
if (!token0 || !token1) return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we throw if it's falsy?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, this is code that currently works for Uniswap and for us, and that's a nice place to be 😅

token0.derivedETH = findEthPerToken(token0 as Token)
token1.derivedETH = findEthPerToken(token1 as Token)
token0.save()
Expand All @@ -80,25 +52,17 @@ export function handleMint(event: MintEvent): void {
let bundle = Bundle.load('1')
let poolAddress = event.address.toHexString()
let pool = Pool.load(poolAddress)
if (!pool) return

const networkName = dataSource.network();
if(!networkName) return

let factory = Factory.load(FACTORY_ADDRESSES[networkName])
let factory = Factory.load(FACTORY_ADDRESS)

let token0 = Token.load(pool.token0)
let token1 = Token.load(pool.token1)
if (!token0 || !token1) return
let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals)

if (!bundle) return
let amountUSD = amount0
.times(token0.derivedETH.times(bundle.ethPriceUSD))
.plus(amount1.times(token1.derivedETH.times(bundle.ethPriceUSD)))

if (!factory) return
// reset tvl aggregates until new amounts calculated
factory.totalValueLockedETH = factory.totalValueLockedETH.minus(pool.totalValueLockedETH)

Expand Down Expand Up @@ -207,17 +171,10 @@ export function handleBurn(event: BurnEvent): void {
let bundle = Bundle.load('1')
let poolAddress = event.address.toHexString()
let pool = Pool.load(poolAddress)
const networkName = dataSource.network();
if(!networkName) return

let factory = Factory.load(FACTORY_ADDRESSES[networkName])

if (!pool) return
let factory = Factory.load(FACTORY_ADDRESS)

let token0 = Token.load(pool.token0)
let token1 = Token.load(pool.token1)

if (!factory || !token0 || !token1 || !bundle) return
let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals)

Expand Down Expand Up @@ -288,7 +245,6 @@ export function handleBurn(event: BurnEvent): void {
let lowerTick = Tick.load(lowerTickId)
let upperTick = Tick.load(upperTickId)
let amount = event.params.amount
if (!lowerTick || !upperTick) return
lowerTick.liquidityGross = lowerTick.liquidityGross.minus(amount)
lowerTick.liquidityNet = lowerTick.liquidityNet.minus(amount)
upperTick.liquidityGross = upperTick.liquidityGross.minus(amount)
Expand All @@ -313,12 +269,8 @@ export function handleBurn(event: BurnEvent): void {

export function handleSwap(event: SwapEvent): void {
let bundle = Bundle.load('1')
const networkName = dataSource.network();
if(!networkName) return

let factory = Factory.load(FACTORY_ADDRESSES[networkName])
let factory = Factory.load(FACTORY_ADDRESS)
let pool = Pool.load(event.address.toHexString())
if (!pool || !factory || !bundle) return

// hot fix for bad pricing
if (pool.id == '0x9663f2ca0454accad3e094448ea6f77443880454') {
Expand All @@ -327,7 +279,6 @@ export function handleSwap(event: SwapEvent): void {

let token0 = Token.load(pool.token0)
let token1 = Token.load(pool.token1)
if (!token0 || !token1) return

let oldTick = pool.tick!

Expand Down Expand Up @@ -550,8 +501,32 @@ export function handleFlash(event: FlashEvent): void {
let poolContract = PoolABI.bind(event.address)
let feeGrowthGlobal0X128 = poolContract.feeGrowthGlobal0X128()
let feeGrowthGlobal1X128 = poolContract.feeGrowthGlobal1X128()
if (!pool) return
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)
}
}
11 changes: 4 additions & 7 deletions src/mappings/factory.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import { WHITELIST_TOKENS } from './../utils/pricing'
/* eslint-disable prefer-const */
import { FACTORY_ADDRESSES, ZERO_BI, ONE_BI, ZERO_BD, ADDRESS_ZERO } from './../utils/constants'
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'
import { Pool, Token, Bundle } from '../types/schema'
import { Pool as PoolTemplate } from '../types/templates'
import { fetchTokenSymbol, fetchTokenName, fetchTokenTotalSupply, fetchTokenDecimals } from '../utils/token'
import { log, BigInt, Address, dataSource } from '@graphprotocol/graph-ts'
import { log, BigInt, Address } from '@graphprotocol/graph-ts'

export function handlePoolCreated(event: PoolCreated): void {
// temp fix
if (event.params.pool == Address.fromHexString('0x8fe8d9bb8eeba3ed688069c3d6b556c9ca258248')) {
return
}

const networkName = dataSource.network();
if(!networkName) return

// load factory
let factory = Factory.load(FACTORY_ADDRESSES[networkName])
let factory = Factory.load(FACTORY_ADDRESS)
if (factory === null) {
factory = new Factory(FACTORY_ADDRESSES[networkName])
factory = new Factory(FACTORY_ADDRESS)
factory.poolCount = ZERO_BI
factory.totalVolumeETH = ZERO_BD
factory.totalVolumeUSD = ZERO_BD
Expand Down
17 changes: 3 additions & 14 deletions src/mappings/position-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ import {
Transfer
} from '../types/NonfungiblePositionManager/NonfungiblePositionManager'
import { Bundle, Position, PositionSnapshot, Token } from '../types/schema'
import { ADDRESS_ZERO, factoryContracts, ZERO_BD, ZERO_BI } from '../utils/constants'
import { Address, BigInt, dataSource, ethereum } from '@graphprotocol/graph-ts'
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 {
const networkName = dataSource.network()
if(!networkName) return null

let position = Position.load(tokenId.toString())
if (position === null) {
let contract = NonfungiblePositionManager.bind(event.address)
Expand All @@ -26,9 +23,7 @@ function getPosition(event: ethereum.Event, tokenId: BigInt): Position | null {
// (e.g. 0xf7867fa19aa65298fadb8d4f72d0daed5e836f3ba01f0b9b9631cdc6c36bed40)
if (!positionCall.reverted) {
let positionResult = positionCall.value
let result = factoryContracts[networkName].try_getPool(positionResult.value2, positionResult.value3, positionResult.value4)
if (result == null || result.reverted) return position
let poolAddress = factoryContracts[networkName].getPool(positionResult.value2, positionResult.value3, positionResult.value4)
let poolAddress = factoryContract.getPool(positionResult.value2, positionResult.value3, positionResult.value4)

position = new Position(tokenId.toString())
// The owner gets correctly updated in the Transfer handler
Expand Down Expand Up @@ -105,8 +100,6 @@ export function handleIncreaseLiquidity(event: IncreaseLiquidity): void {
let token0 = Token.load(position.token0)
let token1 = Token.load(position.token1)

if (!token0 || !token1) return

let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals)

Expand Down Expand Up @@ -141,8 +134,6 @@ export function handleDecreaseLiquidity(event: DecreaseLiquidity): void {

let token0 = Token.load(position.token0)
let token1 = Token.load(position.token1)
if (!token0 || !token1) return

let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals)

Expand All @@ -166,8 +157,6 @@ export function handleCollect(event: Collect): void {
}

let token0 = Token.load(position.token0)
if (!token0) return

let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
position.collectedFeesToken0 = position.collectedFeesToken0.plus(amount0)
position.collectedFeesToken1 = position.collectedFeesToken1.plus(amount0)
Expand Down
11 changes: 3 additions & 8 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,12 @@ import { BigInt, BigDecimal, Address } from '@graphprotocol/graph-ts'
import { Factory as FactoryContract } from '../types/templates/Pool/Factory'

export const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000'
export const FACTORY_ADDRESSES = {
'mainnet': '0x0569168709a869e7f4Ba142c49BFF7faA14f76C8',
'optimism-goerli': '0xEF8894089c991CF9c009Cd66F7F2fb9dC0e2fB19'
}
export const FACTORY_ADDRESS = '0x0569168709a869e7f4Ba142c49BFF7faA14f76C8'

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 BI_18 = BigInt.fromI32(18)

export let factoryContracts = {
'mainnet': FactoryContract.bind(Address.fromString(FACTORY_ADDRESSES['mainnet'])),
'optimism-goerli': FactoryContract.bind(Address.fromString(FACTORY_ADDRESSES['optimism-goerli']))
}
export let factoryContract = FactoryContract.bind(Address.fromString(FACTORY_ADDRESS))
4 changes: 2 additions & 2 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable prefer-const */
import { BigInt, BigDecimal, ethereum } from '@graphprotocol/graph-ts'
import { Transaction } from '../types/schema'
import { ONE_BI, ZERO_BI, ZERO_BD, ONE_BD } from './constants'
import { ONE_BI, ZERO_BI, ZERO_BD, ONE_BD } from '../utils/constants'

export function exponentToBigDecimal(decimals: BigInt): BigDecimal {
let bd = BigDecimal.fromString('1')
Expand Down Expand Up @@ -87,7 +87,7 @@ export function loadTransaction(event: ethereum.Event): Transaction {
}
transaction.blockNumber = event.block.number
transaction.timestamp = event.block.timestamp
transaction.gasUsed = event.transaction.gasLimit
transaction.gasUsed = event.transaction.gasUsed
transaction.gasPrice = event.transaction.gasPrice
transaction.save()
return transaction as Transaction
Expand Down
Loading