-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update Liquidity chart on Analytics page
- Loading branch information
1 parent
fa5c023
commit 168a8af
Showing
2 changed files
with
167 additions
and
32 deletions.
There are no files selected for viewing
198 changes: 167 additions & 31 deletions
198
projects/ui/src/components/Analytics/Bean/Liquidity.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,187 @@ | ||
import React from 'react'; | ||
import { tickFormatUSD } from '~/components/Analytics/formatters'; | ||
import { LineChartProps } from '~/components/Common/Charts/LineChart'; | ||
import SeasonPlot, { | ||
SeasonPlotBaseProps, | ||
} from '~/components/Common/Charts/SeasonPlot'; | ||
import React, { useMemo } from 'react'; | ||
import { | ||
SeasonalLiquidityDocument, | ||
SeasonalLiquidityQuery, | ||
SeasonalLiquidityPerPoolDocument, | ||
} from '~/generated/graphql'; | ||
import useSeason from '~/hooks/beanstalk/useSeason'; | ||
|
||
import { FC } from '~/types'; | ||
import useSeasonsQuery, { SeasonRange } from '~/hooks/beanstalk/useSeasonsQuery'; | ||
import { BaseDataPoint, ChartMultiStyles } from '../../Common/Charts/ChartPropProvider'; | ||
import useSdk from '~/hooks/sdk'; | ||
import useTimeTabState from '~/hooks/app/useTimeTabState'; | ||
import BaseSeasonPlot, { QueryData } from '../../Common/Charts/BaseSeasonPlot'; | ||
import { BEAN_CRV3_V1_LP, BEAN_LUSD_LP } from '~/constants/tokens'; | ||
import { BeanstalkPalette } from '../../App/muiTheme'; | ||
import { SeasonPlotBaseProps } from '~/components/Common/Charts/SeasonPlot'; | ||
|
||
const getValue = (season: SeasonalLiquidityQuery['seasons'][number]) => | ||
parseFloat(season.liquidityUSD); | ||
const formatValue = (value: number) => | ||
`$${value.toLocaleString('en-US', { maximumFractionDigits: 0 })}`; | ||
const statProps = { | ||
/// Setup SeasonPlot | ||
const formatValue = (value: number) => ( | ||
`$${(value || 0).toLocaleString('en-US', { maximumFractionDigits: 2 })}` | ||
); | ||
const StatProps = { | ||
title: 'Liquidity', | ||
titleTooltip: 'The total USD value of tokens in liquidity pools on the Minting Whitelist at the beginning of every Season. Pre-exploit values include liquidity in pools on the Deposit Whitelist.', | ||
gap: 0.25, | ||
}; | ||
const queryConfig = { | ||
variables: { season_gt: 0 }, | ||
context: { subgraph: 'bean' }, | ||
}; | ||
const lineChartProps: Partial<LineChartProps> = { | ||
yTickFormat: tickFormatUSD, | ||
color: 'primary', | ||
sx: { ml: 0 }, | ||
}; | ||
|
||
const Liquidity: FC<{ height?: SeasonPlotBaseProps['height'] }> = ({ | ||
height, | ||
const Liquidity: FC<{ height?: SeasonPlotBaseProps['height'] }> = ({ | ||
height, | ||
}) => { | ||
// | ||
const sdk = useSdk(); | ||
const timeTabParams = useTimeTabState(); | ||
const season = useSeason(); | ||
|
||
const getStatValue = <T extends BaseDataPoint>(v?: T[]) => { | ||
if (!v?.length) return 0; | ||
const dataPoint = v[0]; | ||
return dataPoint?.value || 0; | ||
}; | ||
|
||
const BEAN_LUSD_LP_V1 = BEAN_LUSD_LP[1]; | ||
const BEAN_CRV3_V1 = BEAN_CRV3_V1_LP[1]; | ||
|
||
const poolList = [ | ||
sdk.pools.BEAN_CRV3, | ||
sdk.pools.BEAN_ETH_WELL, | ||
sdk.tokens.BEAN_ETH_UNIV2_LP, | ||
BEAN_LUSD_LP_V1, | ||
BEAN_CRV3_V1, | ||
]; | ||
|
||
const chartStyle: ChartMultiStyles = { | ||
[sdk.pools.BEAN_CRV3.address]: { | ||
stroke: BeanstalkPalette.theme.spring.blue, | ||
fillPrimary: BeanstalkPalette.theme.spring.lightBlue | ||
}, | ||
[sdk.pools.BEAN_ETH_WELL.address]: { | ||
stroke: BeanstalkPalette.theme.spring.beanstalkGreen, | ||
fillPrimary: BeanstalkPalette.theme.spring.washedGreen | ||
}, | ||
[sdk.tokens.BEAN_ETH_UNIV2_LP.address]: { | ||
stroke: BeanstalkPalette.theme.spring.chart.purple, | ||
fillPrimary: BeanstalkPalette.theme.spring.chart.purpleLight | ||
}, | ||
[BEAN_LUSD_LP_V1.address]: { | ||
stroke: BeanstalkPalette.theme.spring.grey, | ||
fillPrimary: BeanstalkPalette.theme.spring.lightishGrey | ||
}, | ||
[BEAN_CRV3_V1.address]: { | ||
stroke: BeanstalkPalette.theme.spring.chart.yellow, | ||
fillPrimary: BeanstalkPalette.theme.spring.chart.yellowLight | ||
}, | ||
}; | ||
|
||
// Filters non-relevant tokens from the tooltip on a per-season basis | ||
const seasonFilter = { | ||
[sdk.tokens.BEAN_ETH_UNIV2_LP.address]: { from: 0, to: 6074 }, | ||
[BEAN_LUSD_LP_V1.address]: { from: 5502, to: 6074 }, | ||
[BEAN_CRV3_V1.address]: { from: 3658, to: 6074 }, | ||
[sdk.pools.BEAN_CRV3.address]: { from: 6074, to: Infinity }, | ||
[sdk.pools.BEAN_ETH_WELL.address]: { from: 15241, to: Infinity }, | ||
}; | ||
|
||
const queryConfigBeanCrv3 = useMemo(() => ({ | ||
variables: { pool: sdk.pools.BEAN_CRV3.address }, | ||
context: { subgraph: 'bean' } | ||
}), [sdk.pools.BEAN_CRV3.address]); | ||
|
||
const queryConfigBeanEthWell = useMemo(() => ({ | ||
variables: { pool: sdk.pools.BEAN_ETH_WELL.address }, | ||
context: { subgraph: 'bean' } | ||
}), [sdk.pools.BEAN_ETH_WELL.address]); | ||
|
||
const queryConfigBeanEthOld = useMemo(() => ({ | ||
variables: { pool: sdk.tokens.BEAN_ETH_UNIV2_LP.address }, | ||
context: { subgraph: 'bean' } | ||
}), [sdk.tokens.BEAN_ETH_UNIV2_LP.address]); | ||
|
||
const queryConfigBeanLusdOld = useMemo(() => ({ | ||
variables: { pool: BEAN_LUSD_LP_V1.address }, | ||
context: { subgraph: 'bean' } | ||
}), [BEAN_LUSD_LP_V1.address]); | ||
|
||
const queryConfigBeanCrv3Old = useMemo(() => ({ | ||
variables: { pool: BEAN_CRV3_V1.address }, | ||
context: { subgraph: 'bean' } | ||
}), [BEAN_CRV3_V1.address]); | ||
|
||
const beanCrv3 = useSeasonsQuery(SeasonalLiquidityPerPoolDocument, timeTabParams[0][1], queryConfigBeanCrv3); | ||
const beanEthWell = useSeasonsQuery(SeasonalLiquidityPerPoolDocument, timeTabParams[0][1], queryConfigBeanEthWell); | ||
const beanEthOld = useSeasonsQuery(SeasonalLiquidityPerPoolDocument, SeasonRange.ALL, queryConfigBeanEthOld); | ||
const beanLusdOld = useSeasonsQuery(SeasonalLiquidityPerPoolDocument, SeasonRange.ALL, queryConfigBeanLusdOld); | ||
const beanCrv3Old = useSeasonsQuery(SeasonalLiquidityPerPoolDocument, SeasonRange.ALL, queryConfigBeanCrv3Old); | ||
|
||
let seasonData | ||
if (timeTabParams[0][1] === SeasonRange.ALL) { | ||
seasonData = [ | ||
beanCrv3.data?.seasons, | ||
beanEthWell.data?.seasons, | ||
beanEthOld.data?.seasons, | ||
beanLusdOld.data?.seasons, | ||
beanCrv3Old.data?.seasons | ||
].flat(Infinity); | ||
} else { | ||
seasonData = [ | ||
beanCrv3.data?.seasons, | ||
beanEthWell.data?.seasons, | ||
].flat(Infinity); | ||
}; | ||
|
||
const loading = beanCrv3.loading || beanEthWell.loading || beanEthOld.loading || beanLusdOld.loading || beanCrv3Old.loading; | ||
|
||
const processedSeasons: any[] = []; | ||
const defaultDataPoint = { | ||
season: 0, | ||
date: 0, | ||
value: 0, | ||
[sdk.pools.BEAN_CRV3.address]: 0, | ||
[sdk.pools.BEAN_ETH_WELL.address]: 0, | ||
[sdk.tokens.BEAN_ETH_UNIV2_LP.address]: 0, | ||
[BEAN_LUSD_LP_V1.address]: 0, | ||
[BEAN_CRV3_V1.address]: 0, | ||
}; | ||
|
||
if (season && !loading && seasonData[0] && seasonData[0].season) { | ||
const latestSeason = seasonData[0].season; | ||
seasonData.forEach((dataPoint) => { | ||
const seasonDiff = latestSeason - dataPoint.season; | ||
if (!processedSeasons[seasonDiff]) { | ||
processedSeasons[seasonDiff] = { ...defaultDataPoint }; | ||
}; | ||
processedSeasons[seasonDiff].season = Number(dataPoint.season); | ||
processedSeasons[seasonDiff].date = new Date(Number(dataPoint.updatedAt) * 1000); | ||
processedSeasons[seasonDiff][dataPoint.id.slice(0, 42)] = Number(dataPoint.liquidityUSD); | ||
processedSeasons[seasonDiff].value += Number(dataPoint.liquidityUSD); | ||
}); | ||
}; | ||
|
||
const queryData: QueryData = { | ||
data: [processedSeasons.filter(Boolean).reverse()], | ||
loading: loading, | ||
keys: poolList.map((pool) => pool.address), | ||
error: undefined, | ||
}; | ||
|
||
return ( | ||
<SeasonPlot | ||
document={SeasonalLiquidityDocument} | ||
<BaseSeasonPlot | ||
queryData={queryData} | ||
height={height} | ||
defaultSeason={season?.gt(0) ? season.toNumber() : 0} | ||
getValue={getValue} | ||
StatProps={StatProps} | ||
timeTabParams={timeTabParams} | ||
formatValue={formatValue} | ||
StatProps={statProps} | ||
LineChartProps={lineChartProps} | ||
queryConfig={queryConfig} | ||
dateKey="timestamp" | ||
stackedArea | ||
ChartProps={{ | ||
getDisplayValue: getStatValue, | ||
tooltip: true, | ||
useOldLpTokens: true, | ||
tokenPerSeasonFilter: seasonFilter, | ||
stylesConfig: chartStyle | ||
}} | ||
/> | ||
); | ||
}; | ||
|
||
export default Liquidity; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters