From 30c1be31e03a688a52d810dc70bfc0b4d970009e Mon Sep 17 00:00:00 2001 From: mihaisc Date: Tue, 23 Nov 2021 14:59:34 +0200 Subject: [PATCH] add pool snapshot --- schema.graphql | 25 ++--- src/mappings/pool.ts | 80 +++++++++++----- src/mappings/utils/constants.ts | 2 + src/mappings/utils/poolUtils.ts | 162 +++++++++++++------------------- 4 files changed, 133 insertions(+), 136 deletions(-) diff --git a/schema.graphql b/schema.graphql index 72d69dd..5d2b8a1 100644 --- a/schema.graphql +++ b/schema.graphql @@ -108,8 +108,13 @@ type Pool @entity { "maximum supply if any, converted from wei" cap: BigDecimal - baseToken: PoolToken! - datatoken: PoolToken! + baseToken: Token! + baseTokenLiquidity: BigDecimal! + baseTokenWeight: BigDecimal! + + datatoken: Token! + datatokenLiquidity: BigDecimal! + datatokenWeight: BigDecimal! "pool Fee percent, fee goes to all liquidity providers : SWAP, JOIN , EXIT" poolFee: BigDecimal! @@ -166,18 +171,6 @@ type Pool @entity { 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 type PoolShares @entity { "poolAddress + userAddress" @@ -216,7 +209,7 @@ type PoolTransaction @entity { marketFee: BigDecimal! "block time when pool was created" - createdTimestamp: Int! + timestamp: Int! "pool creation transaction id" tx: Bytes "block number when it was created" @@ -383,7 +376,7 @@ type PoolSnapshot @entity { "swap fee value 24h" swapFees: BigDecimal! "date without time" - createdTimestamp: Int! + date: Int! "last spot price in the 24h interval" spotPrice: BigDecimal! diff --git a/src/mappings/pool.ts b/src/mappings/pool.ts index 82a7cf1..2906220 100644 --- a/src/mappings/pool.ts +++ b/src/mappings/pool.ts @@ -12,9 +12,9 @@ import { weiToDecimal } from './utils/generic' import { calcSpotPrice, getPool, - getPoolToken, getPoolTransaction, - getPoolShares + getPoolShares, + getPoolSnapshot } from './utils/poolUtils' import { getToken } from './utils/tokenUtils' import { getUser } from './utils/userUtils' @@ -28,7 +28,8 @@ export function handleJoin(event: LOG_JOIN): void { pool.transactionCount = pool.transactionCount.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 ammount = weiToDecimal( event.params.tokenAmountIn.toBigDecimal(), @@ -37,16 +38,22 @@ export function handleJoin(event: LOG_JOIN): void { if (token.isDatatoken) { poolTx.datatoken = token.id poolTx.datatokenValue = ammount + + poolSnapshot.datatokenLiquidity = + poolSnapshot.datatokenLiquidity.plus(ammount) + + pool.datatokenLiquidity.plus(ammount) } else { poolTx.baseToken = token.id poolTx.baseTokenValue = ammount + + poolSnapshot.baseTokenLiquidity = + poolSnapshot.baseTokenLiquidity.plus(ammount) + + pool.baseTokenLiquidity.plus(ammount) } - // update pool token - const poolToken = getPoolToken(pool.id, token.id) - poolToken.balance.plus(ammount) - - poolToken.save() + poolSnapshot.save() poolTx.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. const token = getToken(event.params.tokenOut.toHex()) + const poolSnapshot = getPoolSnapshot(pool.id, event.block.timestamp.toI32()) const ammount = weiToDecimal( event.params.tokenAmountOut.toBigDecimal(), token.decimals @@ -68,15 +76,22 @@ export function handleExit(event: LOG_EXIT): void { if (token.isDatatoken) { poolTx.datatoken = token.id poolTx.datatokenValue = ammount.neg() + + poolSnapshot.datatokenLiquidity = + poolSnapshot.datatokenLiquidity.minus(ammount) + + pool.datatokenLiquidity.minus(ammount) } else { poolTx.baseToken = token.id poolTx.baseTokenValue = ammount.neg() + + poolSnapshot.baseTokenLiquidity = + poolSnapshot.baseTokenLiquidity.minus(ammount) + + pool.baseTokenLiquidity.minus(ammount) } - const poolToken = getPoolToken(pool.id, token.id) - poolToken.balance.minus(ammount) - - poolToken.save() + poolSnapshot.save() poolTx.save() pool.save() } @@ -89,6 +104,7 @@ export function handleSwap(event: LOG_SWAP): void { pool.transactionCount = pool.transactionCount.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 const tokenOut = getToken(event.params.tokenOut.toHex()) const ammountOut = weiToDecimal( @@ -98,12 +114,20 @@ export function handleSwap(event: LOG_SWAP): void { if (tokenOut.isDatatoken) { poolTx.datatoken = tokenOut.id poolTx.datatokenValue = ammountOut.neg() + + pool.datatokenLiquidity = pool.datatokenLiquidity.minus(ammountOut) + + poolSnapshot.datatokenLiquidity = + poolSnapshot.datatokenLiquidity.minus(ammountOut) } else { poolTx.baseToken = tokenOut.id 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 const tokenIn = getToken(event.params.tokenIn.toHex()) @@ -114,12 +138,20 @@ export function handleSwap(event: LOG_SWAP): void { if (tokenIn.isDatatoken) { poolTx.datatoken = tokenIn.id poolTx.datatokenValue = ammountIn + + pool.datatokenLiquidity = pool.datatokenLiquidity.plus(ammountIn) + + poolSnapshot.datatokenLiquidity = + poolSnapshot.datatokenLiquidity.plus(ammountIn) } else { poolTx.baseToken = tokenIn.id 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 const isTokenInDatatoken = tokenIn.isDatatoken @@ -130,28 +162,28 @@ export function handleSwap(event: LOG_SWAP): void { isTokenInDatatoken ? tokenIn.decimals : tokenOut.decimals ) pool.spotPrice = spotPrice + poolSnapshot.spotPrice = spotPrice - poolTokenIn.save() - poolTokenOut.save() + poolSnapshot.save() poolTx.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 { const pool = getPool(event.address.toHex()) const token = getToken(event.params.baseToken.toHex()) - const baseToken = getPoolToken(pool.id, event.params.baseToken.toHex()) - baseToken.denormWeight = weiToDecimal( + pool.baseToken = token.id + pool.baseTokenWeight = weiToDecimal( event.params.baseTokenWeight.toBigDecimal(), token.decimals ) - baseToken.save() // decimals hardcoded because datatokens have 18 decimals - const datatoken = getPoolToken(pool.id, event.params.dataToken.toHex()) - datatoken.denormWeight = weiToDecimal( + const datatoken = getToken(event.params.dataToken.toHex()) + pool.datatoken = datatoken.id + pool.datatokenWeight = weiToDecimal( event.params.dataTokenWeight.toBigDecimal(), 18 ) diff --git a/src/mappings/utils/constants.ts b/src/mappings/utils/constants.ts index 866bc8b..e8d5d7e 100644 --- a/src/mappings/utils/constants.ts +++ b/src/mappings/utils/constants.ts @@ -2,6 +2,8 @@ import { BigDecimal, BigInt } from '@graphprotocol/graph-ts' export const ENABLE_DEBUG = true +export const DAY = 24 * 60 * 60 + export namespace integer { export const NEGATIVE_ONE = BigInt.fromI32(-1) export const ZERO = BigInt.fromI32(0) diff --git a/src/mappings/utils/poolUtils.ts b/src/mappings/utils/poolUtils.ts index 23fc1d6..fb802ac 100644 --- a/src/mappings/utils/poolUtils.ts +++ b/src/mappings/utils/poolUtils.ts @@ -2,11 +2,11 @@ import { Address, BigDecimal, ethereum } from '@graphprotocol/graph-ts' import { Pool, PoolShares, - PoolToken, + PoolSnapshot, PoolTransaction } from '../../@types/schema' import { BPool } from '../../@types/templates/BPool/BPool' -import { PoolTransactionType } from './constants' +import { DAY, decimal, PoolTransactionType } from './constants' import { gweiToEth, weiToDecimal } from './generic' export function getPoolSharesId( @@ -62,26 +62,6 @@ export function getPool(poolAddress: string): 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( poolAddress: string, baseTokenAddress: string, @@ -99,95 +79,85 @@ export function calcSpotPrice( return price } - +export function getDateFromTimestamp(timestamp: i32): i32 { + // date without time + return timestamp - (timestamp % DAY) +} export function getPoolSnapshotId(poolAddress: string, timestamp: i32): string { - const dayTimestamp = timestamp - (timestamp % DAY) // Todays Timestamp - return `${poolAddress}-${dayTimestamp}` + return `${poolAddress}-${getDateFromTimestamp(timestamp)}` } -export function createPoolSnapshot(poolId: string, timestamp: i32): void { - log.warning('Start create Pool Snapshot: {} {}', [ - poolId, - timestamp.toString() - ]) - const dayTimestamp = timestamp - (timestamp % DAY) // Todays Timestamp +export function createPoolSnapshot( + poolAddress: string, + timestamp: i32 +): PoolSnapshot { + const snapshotId = getPoolSnapshotId(poolAddress, timestamp) - const pool = PoolEntity.load(poolId) - - 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 pool = Pool.load(poolAddress) const snapshot = new PoolSnapshot(snapshotId) - snapshot.pool = poolId + snapshot.pool = poolAddress snapshot.totalShares = pool.totalShares - snapshot.swapVolume = ZERO_BD - snapshot.swapFees = pool.totalSwapFee - snapshot.timestamp = dayTimestamp + snapshot.swapVolume = decimal.ZERO + snapshot.swapFees = decimal.ZERO + 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() + return snapshot } -export function saveSwapToSnapshot( +export function getPoolSnapshot( poolAddress: string, - timestamp: i32, - volume: BigDecimal, - fees: BigDecimal -): void { - const dayTimestamp = timestamp - (timestamp % DAY) // Todays timestamp - - // Save pool snapshot - const snapshotId = poolAddress + '-' + dayTimestamp.toString() - const snapshot = PoolSnapshot.load(snapshotId) - - if (!snapshot) { - return + timestamp: i32 +): PoolSnapshot { + let snapshot = PoolSnapshot.load(getPoolSnapshotId(poolAddress, timestamp)) + if (snapshot === null) { + snapshot = createPoolSnapshot(poolAddress, timestamp) } - snapshot.swapVolume = snapshot.swapVolume.plus(volume) - snapshot.swapFees = snapshot.swapFees.plus(fees) - snapshot.save() + return snapshot } -export function updatePoolSnapshotToken( - poolAddress: string, - timestamp: i32, - poolTokenId: string, - amount: BigDecimal, - balance: BigDecimal, - feeValue: BigDecimal -): void { - log.warning('Start create Pool Snapshot Token: {} {}', [ - poolAddress, - timestamp.toString() - ]) - const dayTimestamp = timestamp - (timestamp % DAY) // Todays timestamp +// export function updatePoolSnapshotToken( +// poolAddress: string, +// timestamp: i32, +// poolTokenId: string, +// amount: BigDecimal, +// balance: BigDecimal, +// feeValue: BigDecimal +// ): void { +// log.warning('Start create Pool Snapshot Token: {} {}', [ +// poolAddress, +// timestamp.toString() +// ]) +// const dayTimestamp = timestamp - (timestamp % DAY) // Todays timestamp - const snapshotId = poolAddress + '-' + dayTimestamp.toString() - log.warning('Pool Snapshot Token: {} {} {} {}', [ - amount.toString(), - balance.toString(), - feeValue.toString(), - snapshotId + '-' + poolTokenId - ]) - const token = new PoolSnapshotTokenValue(snapshotId + '-' + poolTokenId) +// const snapshotId = poolAddress + '-' + dayTimestamp.toString() +// log.warning('Pool Snapshot Token: {} {} {} {}', [ +// amount.toString(), +// balance.toString(), +// feeValue.toString(), +// snapshotId + '-' + poolTokenId +// ]) +// const token = new PoolSnapshotTokenValue(snapshotId + '-' + poolTokenId) - token.poolSnapshot = snapshotId - token.value = amount - token.tokenReserve = balance - token.tokenAddress = poolTokenId - token.feeValue = feeValue - if (amount.lt(ZERO_BD)) { - token.type = 'out' - } else { - token.type = 'in' - } - log.warning('Snapshot Token ID: {}', [token.id]) - token.save() -} +// token.poolSnapshot = snapshotId +// token.value = amount +// token.tokenReserve = balance +// token.tokenAddress = poolTokenId +// token.feeValue = feeValue +// if (amount.lt(ZERO_BD)) { +// token.type = 'out' +// } else { +// token.type = 'in' +// } +// log.warning('Snapshot Token ID: {}', [token.id]) +// token.save() +// }