Skip to content

Commit

Permalink
Added AvgLiqEfficiencyChart
Browse files Browse the repository at this point in the history
  • Loading branch information
Ncookiez committed Oct 5, 2023
1 parent 889ca44 commit 274afb0
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 0 deletions.
157 changes: 157 additions & 0 deletions apps/analytics/src/components/Charts/AvgLiqEfficiencyChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import { PrizePool } from '@generationsoftware/hyperstructure-client-js'
import {
useHistoricalTokenPrices,
usePrizeTokenData
} from '@generationsoftware/hyperstructure-react-hooks'
import { formatNumberForDisplay, NETWORK, POOL_TOKEN_ADDRESSES } from '@shared/utilities'
import classNames from 'classnames'
import { useMemo } from 'react'
import { Address, formatUnits } from 'viem'
import { useAllDrawsStatus } from '@hooks/useAllDrawsStatus'
import { useBlocksAtTimestamps } from '@hooks/useBlocksAtTimestamps'
import { useHistoricalLiquidationPairTokenOutPrices } from '@hooks/useHistoricalLiquidationPairTokenOutPrices'
import { useLiquidationEvents } from '@hooks/useLiquidationEvents'
import { useRngTxs } from '@hooks/useRngTxs'
import { LineChart } from './LineChart'

interface AvgLiqEfficiencyChartProps {
prizePool: PrizePool
className?: string
}

export const AvgLiqEfficiencyChart = (props: AvgLiqEfficiencyChartProps) => {
const { prizePool, className } = props

const { data: liquidationEvents } = useLiquidationEvents(prizePool)

const { data: rngTxs } = useRngTxs(prizePool)
const drawIds = rngTxs?.map((txs) => txs.rng.drawId) ?? []

const { data: allDrawsStatus } = useAllDrawsStatus(prizePool, drawIds)

const uniqueOpenedAtTimestamps = new Set(allDrawsStatus?.map((draw) => draw.openedAt))
const { data: openedAtBlocksByTimestamp } = useBlocksAtTimestamps(prizePool?.chainId, [
...uniqueOpenedAtTimestamps
])

const uniqueEndedAtTimestamps = new Set(allDrawsStatus?.map((draw) => draw.endedAt))
const { data: endedAtBlocksByTimestamp } = useBlocksAtTimestamps(
prizePool?.chainId,
[...uniqueEndedAtTimestamps].filter((t) => !!t) as number[]
)

// TODO: this assumes the tokenIn is always POOL (and uses mainnet pricing) - not ideal
const { data: prizeToken } = usePrizeTokenData(prizePool)
const { data: tokenInPrices } = useHistoricalTokenPrices(NETWORK.mainnet, [
POOL_TOKEN_ADDRESSES[NETWORK.mainnet]
])
const prizeTokenPrices =
tokenInPrices[POOL_TOKEN_ADDRESSES[NETWORK.mainnet].toLowerCase() as Address]

const lpAddresses = useMemo(() => {
const addresses = new Set<Address>()
liquidationEvents?.forEach((e) => addresses.add(e.args.liquidationPair))
return [...addresses]
}, [liquidationEvents])

const { data: tokenOutPrices } = useHistoricalLiquidationPairTokenOutPrices(
prizePool?.chainId,
lpAddresses
)

const chartData = useMemo(() => {
if (
!!liquidationEvents &&
!!allDrawsStatus &&
!!openedAtBlocksByTimestamp &&
!!endedAtBlocksByTimestamp &&
!!prizeToken &&
!!prizeTokenPrices &&
!!Object.keys(tokenOutPrices).length
) {
const data: { name: string; percentage: number }[] = []

allDrawsStatus.forEach((draw) => {
const targetTimestamp = !!draw.endedAt
? draw.endedAt - (draw.endedAt - draw.openedAt) / 2
: draw.openedAt
const targetDate = new Date(targetTimestamp * 1_000).toISOString().split('T')[0]
const prizeTokenPrice = prizeTokenPrices.find((entry) => entry.date === targetDate)?.price

const openedAtBlock = openedAtBlocksByTimestamp[draw.openedAt]
const endedAtBlock = !!draw.endedAt ? endedAtBlocksByTimestamp[draw.endedAt] : undefined

if (!!prizeTokenPrice && !!openedAtBlock) {
let totalValueIn = 0
let totalValueOut = 0

const drawLiquidationEvents = liquidationEvents.filter(
(e) =>
e.blockNumber > openedAtBlock.number &&
(draw.endedAt === undefined ||
(!!endedAtBlock && e.blockNumber <= endedAtBlock.number))
)

drawLiquidationEvents.forEach((event) => {
const tokenOut = tokenOutPrices[event.args.liquidationPair]
const tokenOutPrice = tokenOut?.priceHistory.find(
(entry) => entry.date === targetDate
)?.price

if (!!tokenOutPrice) {
const amountIn = parseFloat(formatUnits(event.args.amountIn, prizeToken.decimals))
const amountOut = parseFloat(formatUnits(event.args.amountOut, tokenOut.decimals))

const valueIn = amountIn * prizeTokenPrice
const valueOut = amountOut * tokenOutPrice

totalValueIn += valueIn
totalValueOut += valueOut
}
})

if (!!totalValueIn && !!totalValueOut) {
data.push({ name: `#${draw.id}`, percentage: (totalValueIn / totalValueOut) * 100 })
}
}
})

return data
}
}, [
liquidationEvents,
allDrawsStatus,
openedAtBlocksByTimestamp,
endedAtBlocksByTimestamp,
prizeToken,
prizeTokenPrices,
tokenOutPrices
])

if (!!chartData?.length) {
return (
<div className={classNames('w-full flex flex-col gap-2', className)}>
<span className='ml-2 md:ml-6'>Average Liquidation Efficiency</span>
<LineChart
data={chartData}
lines={[{ id: 'percentage' }]}
tooltip={{
show: true,
formatter: (value) => [
`${formatNumberForDisplay(value, { maximumFractionDigits: 2 })}%`,
'Avg Liq. Efficiency'
],
labelFormatter: (label) => `Draw ${label}`
}}
xAxis={{ interval: 2 }}
yAxis={{
domain: ([dataMin]) => [Math.floor(dataMin), 100],
tickFormatter: (tick) => `${tick}%`
}}
/>
</div>
)
}

return <></>
}
2 changes: 2 additions & 0 deletions apps/analytics/src/views/DrawsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useEffect, useMemo } from 'react'
import { Address } from 'viem'
import { usePublicClient } from 'wagmi'
import { AvgClaimFeePercentagesChart } from '@components/Charts/AvgClaimFeePercentagesChart'
import { AvgLiqEfficiencyChart } from '@components/Charts/AvgLiqEfficiencyChart'
import { DrawCards } from '@components/Draws/DrawCards'
import { useDrawClosedEvents } from '@hooks/useDrawClosedEvents'
import { useDrawRngFeePercentage } from '@hooks/useDrawRngFeePercentage'
Expand Down Expand Up @@ -66,6 +67,7 @@ export const DrawsView = (props: DrawsViewProps) => {
<div className={classNames('w-full flex flex-col gap-6 items-center', className)}>
<div className='w-full grid grid-cols-1 gap-6 md:grid-cols-2'>
<AvgClaimFeePercentagesChart prizePool={prizePool} />
<AvgLiqEfficiencyChart prizePool={prizePool} />
</div>
<DrawCards prizePool={prizePool} />
</div>
Expand Down

0 comments on commit 274afb0

Please sign in to comment.