Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,24 @@ import PoolParametersDaoFees from '@/dex/components/PagePool/PoolDetails/PoolSta
import PoolTotalStaked from '@/dex/components/PagePool/PoolDetails/PoolStats/PoolTotalStaked'
import { StyledInformationSquare16 } from '@/dex/components/PagePool/PoolDetails/PoolStats/styles'
import type { TransferProps } from '@/dex/components/PagePool/types'
import usePoolTotalStaked from '@/dex/hooks/usePoolTotalStaked'
import useStore from '@/dex/store/useStore'
import type { PoolParameters } from '@/dex/types/main.types'
import { formatDisplayDate } from '@/dex/utils/utilsDates'
import Stack from '@mui/material/Stack'
import Box from '@ui/Box'
import { Item, Items } from '@ui/Items'
import Stats from '@ui/Stats'
import { Chip } from '@ui/Typography'
import { FORMAT_OPTIONS, formatNumber } from '@ui/utils'
import { useReleaseChannel } from '@ui-kit/hooks/useLocalStorage'
import dayjs from '@ui-kit/lib/dayjs'
import { t } from '@ui-kit/lib/i18n'
import ActionInfo from '@ui-kit/shared/ui/ActionInfo'
import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces'
import { ReleaseChannel, weiToEther } from '@ui-kit/utils'

const { Spacing } = SizesAndSpaces

const PoolParameters = ({
parameters,
Expand All @@ -28,6 +38,7 @@ const PoolParameters = ({
const isLite = useStore((state) => state.networks.networks[rChainId]?.isLite)
const tvl = useStore((state) => state.pools.tvlMapper[rChainId]?.[rPoolId])
const volume = useStore((state) => state.pools.volumeMapper[rChainId]?.[rPoolId])
const [releaseChannel] = useReleaseChannel()

const haveWrappedCoins = useMemo(() => {
if (poolData?.pool?.wrappedCoins) {
Expand All @@ -36,20 +47,149 @@ const PoolParameters = ({
return false
}, [poolData?.pool?.wrappedCoins])

const liquidityUtilization = useMemo(() => {
if (tvl?.value && volume?.value) {
if (+tvl.value === 0 || +volume.value === 0) {
return formatNumber(0, { style: 'percent', maximumFractionDigits: 0 })
} else {
return formatNumber((Number(volume.value) / Number(tvl.value)) * 100, FORMAT_OPTIONS.PERCENT)
}
} else {
return '-'
}
}, [tvl, volume])
const liquidityUtilization = useMemo(
() =>
tvl?.value && volume?.value
? +tvl.value && +volume.value
? formatNumber((+volume.value / +tvl.value) * 100, FORMAT_OPTIONS.PERCENT)
: formatNumber(0, { style: 'percent', maximumFractionDigits: 0 })
: '-',
[tvl, volume],
)

const staked = usePoolTotalStaked(poolDataCacheOrApi)
const { A, initial_A, initial_A_time, future_A, future_A_time, virtualPrice } = parameters ?? {}

const { gamma, adminFee, fee } = parameters ?? {}
if (releaseChannel === ReleaseChannel.Beta) {
const isEymaPools = rChainId === 250 && poolDataCacheOrApi.pool.id.startsWith('factory-eywa')
return (
<Stack gap={Spacing.lg}>
<Stack gap={Spacing.sm}>
{!isLite && (
<>
<ActionInfo
label={t`Daily USD volume`}
value={formatNumber(volume?.value, { notation: 'compact', defaultValue: '-' })}
/>
<ActionInfo
label={t`Liquidity utilization`}
value={liquidityUtilization}
valueTooltip={t`24h Volume/Liquidity ratio`}
/>
</>
)}

<ActionInfo
label={t`Total LP Tokens staked:`}
value={
staked?.gaugeTotalSupply === 'string'
? staked.gaugeTotalSupply
: formatNumber(staked?.gaugeTotalSupply && weiToEther(+staked.gaugeTotalSupply), {
notation: 'compact',
defaultValue: '-',
})
}
/>
<ActionInfo
label={t`Staked percent`}
value={
typeof staked?.totalStakedPercent === 'string'
? staked.totalStakedPercent
: formatNumber(staked?.totalStakedPercent, { style: 'percent', defaultValue: '-' })
}
/>

<ActionInfo label={t`Fee`} value={formatNumber(fee, { style: 'percent', maximumFractionDigits: 4 })} />

{adminFee != null && (
<>
<ActionInfo
label={t`DAO fee`}
valueTooltip={t`The total fee on each trade is split in two parts: one part goes to the pool’s Liquidity Providers, another part goes to the DAO (i.e. Curve veCRV holders)`}
value={formatNumber(isEymaPools ? +adminFee / 2 : adminFee, {
style: 'percent',
maximumFractionDigits: 4,
})}
/>
{isEymaPools && <ActionInfo label={`EYWA fee`} value={+adminFee / 2} />}
</>
)}

<ActionInfo
label={t`Virtual price`}
value={formatNumber(parameters?.virtualPrice, { maximumFractionDigits: 8, defaultValue: '-' })}
valueTooltip={t`Measures pool growth; this is not a dollar value`}
/>
</Stack>

{/* price oracle & price scale */}
{poolData && haveWrappedCoins && (parameters.priceOracle || parameters.priceScale) && !pricesApi && (
<Stack spacing={Spacing.sm}>
<Title>Price Data</Title>
{parameters.priceOracle && (
<ActionInfo
label={t`Price Oracle`}
value={parameters.priceOracle.map((p, idx) => (
<strong key={p}>
{poolData.pool.wrappedCoins[idx + 1]}: {formatNumber(p, { maximumFractionDigits: 10 })}
</strong>
))}
/>
)}
{parameters.priceScale && (
<ActionInfo
label={t`Price Scale`}
value={parameters.priceScale.map((p, idx) => (
<strong key={p}>
{poolData.pool.wrappedCoins[idx + 1]}: {formatNumber(p, { maximumFractionDigits: 10 })}
</strong>
))}
/>
)}
</Stack>
)}

{!pricesApi && (
<Stack spacing={Spacing.sm}>
<Title>{t`Pool Parameters`}</Title>
{gamma && <ActionInfo label={t`Gamma`} value={formatNumber(gamma, { useGrouping: false })} />}
{virtualPrice && (
<ActionInfo
label={t`A`}
value={formatNumber(A, { useGrouping: false })}
valueTooltip={
<Stack gap={Spacing.sm}>
{t`Amplification coefficient chosen from fluctuation of prices around 1.`}
{future_A_time != null &&
dayjs().isAfter(future_A_time, 'day') &&
t`Last change occurred between ${formatDisplayDate(dayjs(initial_A_time))} and ${formatDisplayDate(
dayjs(future_A_time),
)}, when A ramped from ${initial_A} to ${future_A}.`}
</Stack>
}
/>
)}
{future_A_time != null && !dayjs().isAfter(future_A_time, 'day') && (
<>
<ActionInfo
label={t`Ramping A`}
valueTooltip={t`Slowly changing up A so that it doesn't negatively change virtual price growth of shares`}
prevValue={formatNumber(initial_A, { useGrouping: false })}
value={formatNumber(future_A, { useGrouping: false })}
/>
<ActionInfo
label=" "
value={`${formatDisplayDate(dayjs(initial_A_time))} to ${formatDisplayDate(dayjs(future_A_time))}`}
/>
</>
)}
</Stack>
)}
<Contracts rChainId={rChainId} poolDataCacheOrApi={poolDataCacheOrApi} />
</Stack>
)
}
return (
<>
{!isLite && (
Expand Down
7 changes: 6 additions & 1 deletion packages/curve-ui-kit/src/shared/ui/AddressActionInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ export const AddressActionInfo = ({ network, title, address, isBorderBottom }: A
)
}
copyValue={address}
{...(isBorderBottom && { sx: { borderBottom: (t) => `1px solid ${t.palette.divider}` } })}
sx={{
alignItems: 'center',
...(isBorderBottom && {
borderBottom: (t) => `1px solid ${t.palette.divider}`,
}),
}}
/>
)