add pool snapshot

This commit is contained in:
mihaisc 2021-11-23 14:59:34 +02:00
parent 9fcdbf6ce3
commit 30c1be31e0
4 changed files with 133 additions and 136 deletions

View File

@ -108,8 +108,13 @@ type Pool @entity {
"maximum supply if any, converted from wei" "maximum supply if any, converted from wei"
cap: BigDecimal cap: BigDecimal
baseToken: PoolToken! baseToken: Token!
datatoken: PoolToken! baseTokenLiquidity: BigDecimal!
baseTokenWeight: BigDecimal!
datatoken: Token!
datatokenLiquidity: BigDecimal!
datatokenWeight: BigDecimal!
"pool Fee percent, fee goes to all liquidity providers : SWAP, JOIN , EXIT" "pool Fee percent, fee goes to all liquidity providers : SWAP, JOIN , EXIT"
poolFee: BigDecimal! poolFee: BigDecimal!
@ -166,18 +171,6 @@ type Pool @entity {
transactions: [PoolTransaction!] @derivedFrom(field: "pool") transactions: [PoolTransaction!] @derivedFrom(field: "pool")
} }
# should not pe @entity
type PoolToken @entity {
"pool address + token address"
id: ID!
pool: Pool!
token: Token!
"balance of the token in this pool"
balance: BigDecimal!
"weight of token in the pool (50% for ocean bpools)"
denormWeight: BigDecimal!
}
# we will need to track pool share tx between users - bpool transfer tx event # we will need to track pool share tx between users - bpool transfer tx event
type PoolShares @entity { type PoolShares @entity {
"poolAddress + userAddress" "poolAddress + userAddress"
@ -216,7 +209,7 @@ type PoolTransaction @entity {
marketFee: BigDecimal! marketFee: BigDecimal!
"block time when pool was created" "block time when pool was created"
createdTimestamp: Int! timestamp: Int!
"pool creation transaction id" "pool creation transaction id"
tx: Bytes tx: Bytes
"block number when it was created" "block number when it was created"
@ -383,7 +376,7 @@ type PoolSnapshot @entity {
"swap fee value 24h" "swap fee value 24h"
swapFees: BigDecimal! swapFees: BigDecimal!
"date without time" "date without time"
createdTimestamp: Int! date: Int!
"last spot price in the 24h interval" "last spot price in the 24h interval"
spotPrice: BigDecimal! spotPrice: BigDecimal!

View File

@ -12,9 +12,9 @@ import { weiToDecimal } from './utils/generic'
import { import {
calcSpotPrice, calcSpotPrice,
getPool, getPool,
getPoolToken,
getPoolTransaction, getPoolTransaction,
getPoolShares getPoolShares,
getPoolSnapshot
} from './utils/poolUtils' } from './utils/poolUtils'
import { getToken } from './utils/tokenUtils' import { getToken } from './utils/tokenUtils'
import { getUser } from './utils/userUtils' import { getUser } from './utils/userUtils'
@ -28,7 +28,8 @@ export function handleJoin(event: LOG_JOIN): void {
pool.transactionCount = pool.transactionCount.plus(integer.ONE) pool.transactionCount = pool.transactionCount.plus(integer.ONE)
pool.joinCount = pool.joinCount.plus(integer.ONE) pool.joinCount = pool.joinCount.plus(integer.ONE)
// get token, update pool transaction and update pool user liquidity // get token, update pool transaction, poolSnapshot
const poolSnapshot = getPoolSnapshot(pool.id, event.block.timestamp.toI32())
const token = getToken(event.params.tokenIn.toHex()) const token = getToken(event.params.tokenIn.toHex())
const ammount = weiToDecimal( const ammount = weiToDecimal(
event.params.tokenAmountIn.toBigDecimal(), event.params.tokenAmountIn.toBigDecimal(),
@ -37,16 +38,22 @@ export function handleJoin(event: LOG_JOIN): void {
if (token.isDatatoken) { if (token.isDatatoken) {
poolTx.datatoken = token.id poolTx.datatoken = token.id
poolTx.datatokenValue = ammount poolTx.datatokenValue = ammount
poolSnapshot.datatokenLiquidity =
poolSnapshot.datatokenLiquidity.plus(ammount)
pool.datatokenLiquidity.plus(ammount)
} else { } else {
poolTx.baseToken = token.id poolTx.baseToken = token.id
poolTx.baseTokenValue = ammount poolTx.baseTokenValue = ammount
poolSnapshot.baseTokenLiquidity =
poolSnapshot.baseTokenLiquidity.plus(ammount)
pool.baseTokenLiquidity.plus(ammount)
} }
// update pool token poolSnapshot.save()
const poolToken = getPoolToken(pool.id, token.id)
poolToken.balance.plus(ammount)
poolToken.save()
poolTx.save() poolTx.save()
pool.save() pool.save()
} }
@ -61,6 +68,7 @@ export function handleExit(event: LOG_EXIT): void {
// get token and update pool transaction, value is negative because this is an exit event. // get token and update pool transaction, value is negative because this is an exit event.
const token = getToken(event.params.tokenOut.toHex()) const token = getToken(event.params.tokenOut.toHex())
const poolSnapshot = getPoolSnapshot(pool.id, event.block.timestamp.toI32())
const ammount = weiToDecimal( const ammount = weiToDecimal(
event.params.tokenAmountOut.toBigDecimal(), event.params.tokenAmountOut.toBigDecimal(),
token.decimals token.decimals
@ -68,15 +76,22 @@ export function handleExit(event: LOG_EXIT): void {
if (token.isDatatoken) { if (token.isDatatoken) {
poolTx.datatoken = token.id poolTx.datatoken = token.id
poolTx.datatokenValue = ammount.neg() poolTx.datatokenValue = ammount.neg()
poolSnapshot.datatokenLiquidity =
poolSnapshot.datatokenLiquidity.minus(ammount)
pool.datatokenLiquidity.minus(ammount)
} else { } else {
poolTx.baseToken = token.id poolTx.baseToken = token.id
poolTx.baseTokenValue = ammount.neg() poolTx.baseTokenValue = ammount.neg()
poolSnapshot.baseTokenLiquidity =
poolSnapshot.baseTokenLiquidity.minus(ammount)
pool.baseTokenLiquidity.minus(ammount)
} }
const poolToken = getPoolToken(pool.id, token.id) poolSnapshot.save()
poolToken.balance.minus(ammount)
poolToken.save()
poolTx.save() poolTx.save()
pool.save() pool.save()
} }
@ -89,6 +104,7 @@ export function handleSwap(event: LOG_SWAP): void {
pool.transactionCount = pool.transactionCount.plus(integer.ONE) pool.transactionCount = pool.transactionCount.plus(integer.ONE)
pool.joinCount = pool.joinCount.plus(integer.ONE) pool.joinCount = pool.joinCount.plus(integer.ONE)
const poolSnapshot = getPoolSnapshot(pool.id, event.block.timestamp.toI32())
// get token out and update pool transaction, value is negative // get token out and update pool transaction, value is negative
const tokenOut = getToken(event.params.tokenOut.toHex()) const tokenOut = getToken(event.params.tokenOut.toHex())
const ammountOut = weiToDecimal( const ammountOut = weiToDecimal(
@ -98,12 +114,20 @@ export function handleSwap(event: LOG_SWAP): void {
if (tokenOut.isDatatoken) { if (tokenOut.isDatatoken) {
poolTx.datatoken = tokenOut.id poolTx.datatoken = tokenOut.id
poolTx.datatokenValue = ammountOut.neg() poolTx.datatokenValue = ammountOut.neg()
pool.datatokenLiquidity = pool.datatokenLiquidity.minus(ammountOut)
poolSnapshot.datatokenLiquidity =
poolSnapshot.datatokenLiquidity.minus(ammountOut)
} else { } else {
poolTx.baseToken = tokenOut.id poolTx.baseToken = tokenOut.id
poolTx.baseTokenValue = ammountOut.neg() poolTx.baseTokenValue = ammountOut.neg()
pool.baseTokenLiquidity = pool.baseTokenLiquidity.minus(ammountOut)
poolSnapshot.baseTokenLiquidity =
poolSnapshot.baseTokenLiquidity.minus(ammountOut)
} }
const poolTokenOut = getPoolToken(pool.id, tokenOut.id)
poolTokenOut.balance.minus(ammountOut)
// update pool token in // update pool token in
const tokenIn = getToken(event.params.tokenIn.toHex()) const tokenIn = getToken(event.params.tokenIn.toHex())
@ -114,12 +138,20 @@ export function handleSwap(event: LOG_SWAP): void {
if (tokenIn.isDatatoken) { if (tokenIn.isDatatoken) {
poolTx.datatoken = tokenIn.id poolTx.datatoken = tokenIn.id
poolTx.datatokenValue = ammountIn poolTx.datatokenValue = ammountIn
pool.datatokenLiquidity = pool.datatokenLiquidity.plus(ammountIn)
poolSnapshot.datatokenLiquidity =
poolSnapshot.datatokenLiquidity.plus(ammountIn)
} else { } else {
poolTx.baseToken = tokenIn.id poolTx.baseToken = tokenIn.id
poolTx.baseTokenValue = ammountIn poolTx.baseTokenValue = ammountIn
pool.baseTokenLiquidity = pool.baseTokenLiquidity.plus(ammountIn)
poolSnapshot.baseTokenLiquidity =
poolSnapshot.baseTokenLiquidity.plus(ammountIn)
} }
const poolTokenIn = getPoolToken(pool.id, tokenIn.id)
poolTokenIn.balance.plus(ammountIn)
// update spot price // update spot price
const isTokenInDatatoken = tokenIn.isDatatoken const isTokenInDatatoken = tokenIn.isDatatoken
@ -130,28 +162,28 @@ export function handleSwap(event: LOG_SWAP): void {
isTokenInDatatoken ? tokenIn.decimals : tokenOut.decimals isTokenInDatatoken ? tokenIn.decimals : tokenOut.decimals
) )
pool.spotPrice = spotPrice pool.spotPrice = spotPrice
poolSnapshot.spotPrice = spotPrice
poolTokenIn.save() poolSnapshot.save()
poolTokenOut.save()
poolTx.save() poolTx.save()
pool.save() pool.save()
} }
// setup is just to set token weight and spotPrice , it will mostly be 50:50 // setup is just to set token weight(it will mostly be 50:50) and spotPrice
export function handleSetup(event: LOG_SETUP): void { export function handleSetup(event: LOG_SETUP): void {
const pool = getPool(event.address.toHex()) const pool = getPool(event.address.toHex())
const token = getToken(event.params.baseToken.toHex()) const token = getToken(event.params.baseToken.toHex())
const baseToken = getPoolToken(pool.id, event.params.baseToken.toHex()) pool.baseToken = token.id
baseToken.denormWeight = weiToDecimal( pool.baseTokenWeight = weiToDecimal(
event.params.baseTokenWeight.toBigDecimal(), event.params.baseTokenWeight.toBigDecimal(),
token.decimals token.decimals
) )
baseToken.save()
// decimals hardcoded because datatokens have 18 decimals // decimals hardcoded because datatokens have 18 decimals
const datatoken = getPoolToken(pool.id, event.params.dataToken.toHex()) const datatoken = getToken(event.params.dataToken.toHex())
datatoken.denormWeight = weiToDecimal( pool.datatoken = datatoken.id
pool.datatokenWeight = weiToDecimal(
event.params.dataTokenWeight.toBigDecimal(), event.params.dataTokenWeight.toBigDecimal(),
18 18
) )

View File

@ -2,6 +2,8 @@ import { BigDecimal, BigInt } from '@graphprotocol/graph-ts'
export const ENABLE_DEBUG = true export const ENABLE_DEBUG = true
export const DAY = 24 * 60 * 60
export namespace integer { export namespace integer {
export const NEGATIVE_ONE = BigInt.fromI32(-1) export const NEGATIVE_ONE = BigInt.fromI32(-1)
export const ZERO = BigInt.fromI32(0) export const ZERO = BigInt.fromI32(0)

View File

@ -2,11 +2,11 @@ import { Address, BigDecimal, ethereum } from '@graphprotocol/graph-ts'
import { import {
Pool, Pool,
PoolShares, PoolShares,
PoolToken, PoolSnapshot,
PoolTransaction PoolTransaction
} from '../../@types/schema' } from '../../@types/schema'
import { BPool } from '../../@types/templates/BPool/BPool' import { BPool } from '../../@types/templates/BPool/BPool'
import { PoolTransactionType } from './constants' import { DAY, decimal, PoolTransactionType } from './constants'
import { gweiToEth, weiToDecimal } from './generic' import { gweiToEth, weiToDecimal } from './generic'
export function getPoolSharesId( export function getPoolSharesId(
@ -62,26 +62,6 @@ export function getPool(poolAddress: string): Pool {
return pool return pool
} }
export function getPoolTokenId(
poolAddress: string,
tokenAddress: string
): string {
return `${poolAddress}-${tokenAddress}`
}
export function getPoolToken(
poolAddress: string,
tokenAddress: string
): PoolToken {
let poolToken = PoolToken.load(getPoolTokenId(poolAddress, tokenAddress))
if (poolToken === null) {
poolToken = new PoolToken(getPoolTokenId(poolAddress, tokenAddress))
// TODO: add data to pooltoken
}
return poolToken
}
export function calcSpotPrice( export function calcSpotPrice(
poolAddress: string, poolAddress: string,
baseTokenAddress: string, baseTokenAddress: string,
@ -99,95 +79,85 @@ export function calcSpotPrice(
return price return price
} }
export function getDateFromTimestamp(timestamp: i32): i32 {
// date without time
return timestamp - (timestamp % DAY)
}
export function getPoolSnapshotId(poolAddress: string, timestamp: i32): string { export function getPoolSnapshotId(poolAddress: string, timestamp: i32): string {
const dayTimestamp = timestamp - (timestamp % DAY) // Todays Timestamp return `${poolAddress}-${getDateFromTimestamp(timestamp)}`
return `${poolAddress}-${dayTimestamp}`
} }
export function createPoolSnapshot(poolId: string, timestamp: i32): void { export function createPoolSnapshot(
log.warning('Start create Pool Snapshot: {} {}', [ poolAddress: string,
poolId, timestamp: i32
timestamp.toString() ): PoolSnapshot {
]) const snapshotId = getPoolSnapshotId(poolAddress, timestamp)
const dayTimestamp = timestamp - (timestamp % DAY) // Todays Timestamp
const pool = PoolEntity.load(poolId) const pool = Pool.load(poolAddress)
log.warning('got pool {} {}', [pool.id, poolId])
// Save pool snapshot
const snapshotId = poolId + '-' + dayTimestamp.toString()
log.warning('Creatnig Pool Snapshot with id {} {} {}', [
snapshotId,
pool.totalShares.toString(),
pool.totalSwapFee.toString()
])
const snapshot = new PoolSnapshot(snapshotId) const snapshot = new PoolSnapshot(snapshotId)
snapshot.pool = poolId snapshot.pool = poolAddress
snapshot.totalShares = pool.totalShares snapshot.totalShares = pool.totalShares
snapshot.swapVolume = ZERO_BD snapshot.swapVolume = decimal.ZERO
snapshot.swapFees = pool.totalSwapFee snapshot.swapFees = decimal.ZERO
snapshot.timestamp = dayTimestamp snapshot.baseToken = pool.baseToken
//snapshot.baseTokenLiquidity = pool.baseToken
snapshot.datatoken = pool.datatoken
snapshot.datatokenLiquidity = decimal.ZERO
snapshot.date = getDateFromTimestamp(timestamp)
snapshot.spotPrice = pool.spotPrice
snapshot.save() snapshot.save()
return snapshot
} }
export function saveSwapToSnapshot( export function getPoolSnapshot(
poolAddress: string, poolAddress: string,
timestamp: i32, timestamp: i32
volume: BigDecimal, ): PoolSnapshot {
fees: BigDecimal let snapshot = PoolSnapshot.load(getPoolSnapshotId(poolAddress, timestamp))
): void { if (snapshot === null) {
const dayTimestamp = timestamp - (timestamp % DAY) // Todays timestamp snapshot = createPoolSnapshot(poolAddress, timestamp)
// Save pool snapshot
const snapshotId = poolAddress + '-' + dayTimestamp.toString()
const snapshot = PoolSnapshot.load(snapshotId)
if (!snapshot) {
return
} }
snapshot.swapVolume = snapshot.swapVolume.plus(volume) return snapshot
snapshot.swapFees = snapshot.swapFees.plus(fees)
snapshot.save()
} }
export function updatePoolSnapshotToken( // export function updatePoolSnapshotToken(
poolAddress: string, // poolAddress: string,
timestamp: i32, // timestamp: i32,
poolTokenId: string, // poolTokenId: string,
amount: BigDecimal, // amount: BigDecimal,
balance: BigDecimal, // balance: BigDecimal,
feeValue: BigDecimal // feeValue: BigDecimal
): void { // ): void {
log.warning('Start create Pool Snapshot Token: {} {}', [ // log.warning('Start create Pool Snapshot Token: {} {}', [
poolAddress, // poolAddress,
timestamp.toString() // timestamp.toString()
]) // ])
const dayTimestamp = timestamp - (timestamp % DAY) // Todays timestamp // const dayTimestamp = timestamp - (timestamp % DAY) // Todays timestamp
const snapshotId = poolAddress + '-' + dayTimestamp.toString() // const snapshotId = poolAddress + '-' + dayTimestamp.toString()
log.warning('Pool Snapshot Token: {} {} {} {}', [ // log.warning('Pool Snapshot Token: {} {} {} {}', [
amount.toString(), // amount.toString(),
balance.toString(), // balance.toString(),
feeValue.toString(), // feeValue.toString(),
snapshotId + '-' + poolTokenId // snapshotId + '-' + poolTokenId
]) // ])
const token = new PoolSnapshotTokenValue(snapshotId + '-' + poolTokenId) // const token = new PoolSnapshotTokenValue(snapshotId + '-' + poolTokenId)
token.poolSnapshot = snapshotId // token.poolSnapshot = snapshotId
token.value = amount // token.value = amount
token.tokenReserve = balance // token.tokenReserve = balance
token.tokenAddress = poolTokenId // token.tokenAddress = poolTokenId
token.feeValue = feeValue // token.feeValue = feeValue
if (amount.lt(ZERO_BD)) { // if (amount.lt(ZERO_BD)) {
token.type = 'out' // token.type = 'out'
} else { // } else {
token.type = 'in' // token.type = 'in'
} // }
log.warning('Snapshot Token ID: {}', [token.id]) // log.warning('Snapshot Token ID: {}', [token.id])
token.save() // token.save()
} // }