diff --git a/projects/subgraph-basin/schema.graphql b/projects/subgraph-basin/schema.graphql index ac42117ad6..5a6ad8b8ac 100644 --- a/projects/subgraph-basin/schema.graphql +++ b/projects/subgraph-basin/schema.graphql @@ -131,6 +131,12 @@ type Well @entity { " Total number of trades (swaps) " cumulativeSwapCount: Int! + " Current rolling 24 volume in USD " + rollingDailyVolumeUSD: BigDecimal! + + " Current rolling weekly volume in USD " + rollingWeeklyVolumeUSD: BigDecimal! + " Day ID of the most recent daily snapshot " lastSnapshotDayID: Int! diff --git a/projects/subgraph-basin/src/utils/Well.ts b/projects/subgraph-basin/src/utils/Well.ts index c34c582816..bc7d5c276b 100644 --- a/projects/subgraph-basin/src/utils/Well.ts +++ b/projects/subgraph-basin/src/utils/Well.ts @@ -49,6 +49,8 @@ export function createWell(wellAddress: Address, implementation: Address, inputT well.cumulativeDepositCount = 0; well.cumulativeWithdrawCount = 0; well.cumulativeSwapCount = 0; + well.rollingDailyVolumeUSD = ZERO_BD; + well.rollingWeeklyVolumeUSD = ZERO_BD; well.lastSnapshotDayID = 0; well.lastSnapshotHourID = 0; well.lastUpdateTimestamp = ZERO_BI; @@ -92,6 +94,12 @@ export function updateWellVolumes( let usdVolume = toDecimal(amountIn, swapToken.decimals).times(swapToken.lastPriceUSD); + // Remove liquidity one token has no input token amount to calculate volume. + if (amountIn == ZERO_BI) { + swapToken = loadToken(toToken); + usdVolume = toDecimal(amountOut.div(BigInt.fromI32(2)), swapToken.decimals).times(swapToken.lastPriceUSD); + } + // Update fromToken amounts let volumeReserves = well.cumulativeVolumeReserves; @@ -286,6 +294,24 @@ export function takeWellHourlySnapshot(wellAddress: Address, hourID: i32, timest newSnapshot.lastUpdateTimestamp = timestamp; newSnapshot.lastUpdateBlockNumber = blockNumber; newSnapshot.save(); + + // Update the rolling daily and weekly volumes + well.rollingDailyVolumeUSD = newSnapshot.deltaVolumeUSD; + well.rollingWeeklyVolumeUSD = newSnapshot.deltaVolumeUSD; + for (let i = 1; i < 168; i++) { + let snapshot = WellHourlySnapshot.load(wellAddress.concatI32(hourID - i)); + if (snapshot == null) { + // We hit the last snapshot to total + break; + } + if (i < 24) { + well.rollingDailyVolumeUSD = well.rollingDailyVolumeUSD.plus(snapshot.deltaVolumeUSD); + well.rollingWeeklyVolumeUSD = well.rollingWeeklyVolumeUSD.plus(snapshot.deltaVolumeUSD); + } else { + well.rollingWeeklyVolumeUSD = well.rollingWeeklyVolumeUSD.plus(snapshot.deltaVolumeUSD); + } + } + well.save(); } export function loadOrCreateWellHourlySnapshot( diff --git a/projects/subgraph-bean/src/BeanWellHandler.ts b/projects/subgraph-bean/src/BeanWellHandler.ts index 15244856d5..30f8daf5ce 100644 --- a/projects/subgraph-bean/src/BeanWellHandler.ts +++ b/projects/subgraph-bean/src/BeanWellHandler.ts @@ -13,7 +13,8 @@ export function handleAddLiquidity(event: AddLiquidity): void { event.block.timestamp, event.block.number, event.params.tokenAmountsIn[0], - event.params.tokenAmountsIn[1] + event.params.tokenAmountsIn[1], + false ); } @@ -23,7 +24,8 @@ export function handleRemoveLiquidity(event: RemoveLiquidity): void { event.block.timestamp, event.block.number, event.params.tokenAmountsOut[0], - event.params.tokenAmountsOut[1] + event.params.tokenAmountsOut[1], + true ); } @@ -33,7 +35,8 @@ export function handleRemoveLiquidityOneToken(event: RemoveLiquidityOneToken): v event.block.timestamp, event.block.number, event.params.tokenOut == BEAN_ERC20 ? event.params.tokenAmountOut : ZERO_BI, - event.params.tokenOut != BEAN_ERC20 ? event.params.tokenAmountOut : ZERO_BI + event.params.tokenOut != BEAN_ERC20 ? event.params.tokenAmountOut : ZERO_BI, + true ); } @@ -42,13 +45,13 @@ export function handleSync(event: Sync): void { let deltaReserves = deltaBigIntArray(event.params.reserves, pool.reserves); - handleLiquidityChange(event.address.toHexString(), event.block.timestamp, event.block.number, deltaReserves[0], deltaReserves[1]); + handleLiquidityChange(event.address.toHexString(), event.block.timestamp, event.block.number, deltaReserves[0], deltaReserves[1], false); } export function handleSwap(event: Swap): void { handleSwapEvent( event.address.toHexString(), - event.params.fromToken, + event.params.toToken, event.params.amountIn, event.params.amountOut, event.block.timestamp, @@ -76,7 +79,8 @@ function handleLiquidityChange( timestamp: BigInt, blockNumber: BigInt, token0Amount: BigInt, - token1Amount: BigInt + token1Amount: BigInt, + removal: boolean ): void { // Get Price Details via Price contract let beanstalkPrice = BeanstalkPrice.bind(BEANSTALK_PRICE); @@ -97,8 +101,9 @@ function handleLiquidityChange( let volumeUSD = ZERO_BD; let volumeBean = ZERO_BI; - if (token0Amount == ZERO_BI || token1Amount == ZERO_BI) { - volumeUSD = deltaLiquidityUSD; + if ((token0Amount == ZERO_BI || token1Amount == ZERO_BI) && removal) { + // This is a removal and delta liquidity should always be negative. + volumeUSD = deltaLiquidityUSD.times(BigDecimal.fromString("-1")).div(BigDecimal.fromString("2")); volumeBean = BigInt.fromString(volumeUSD.div(newPrice).times(BigDecimal.fromString("1000000")).truncate(0).toString()); }