Skip to content

Commit

Permalink
feat: mint market graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielSchiavini committed Jan 28, 2025
1 parent 80d71d6 commit daef206
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { t } from '@lingui/macro'
import { useMemo } from 'react'
import { meanBy } from 'lodash'
import Box from '@mui/material/Box'
import { useCrvUsdSnapshots } from '@/loan/entities/crvusd'

const graphSize = { width: 172, height: 48 }

Expand All @@ -18,10 +19,10 @@ type GraphType = 'borrow' | 'lend'
/**
* Get the color for the line graph. Will be green if the last value is higher than the first, red if lower, and blue if equal.
*/
function getColor(design: DesignSystem, data: LendingSnapshot[], type: GraphType) {
function getColor<T>(design: DesignSystem, data: T[], snapshotKey: keyof T) {
if (!data.length) return undefined
const first = data[0][`${type}_apy`]
const last = data[data.length - 1][`${type}_apy`]
const first = data[0][snapshotKey]
const last = data[data.length - 1][snapshotKey]
return design.Layer.Feedback[last === first ? 'Info' : last < first ? 'Error' : 'Success']
}

Expand All @@ -33,33 +34,36 @@ const calculateDomain =
return [first - diff, first + diff]
}

/**
* Line graph cell that displays the average historical APY for a vault and a given type (borrow or lend).
*/
export const LineGraphCell = ({
market,
type,
showChart,
}: {
type LineGraphCellProps = {
market: LlamaMarket
type: GraphType
showChart: boolean // chart is hidden depending on the chart settings
}) => {
const { data: snapshots, isLoading } = useLendingSnapshots(
{
blockchainId: market.blockchainId,
contractAddress: market.controllerAddress,
},
market.type == LlamaMarketType.Pool,
)
const { design } = useTheme()
const currentValue = market.rates[type]
const snapshotKey = `${type}_apy` as const
}

function useSnapshots({ address, blockchainId, controllerAddress, type: marketType }: LlamaMarket, type: GraphType) {
const isPool = marketType == LlamaMarketType.Pool
const showMintGraph = !isPool && type === 'borrow'
const contractAddress = isPool ? controllerAddress : address
const params = { blockchainId: blockchainId, contractAddress }
const { data: poolSnapshots, isLoading: poolIsLoading } = useLendingSnapshots(params, isPool)
const { data: mintSnapshots, isLoading: mintIsLoading } = useCrvUsdSnapshots(params, showMintGraph)
if (isPool) {
return { snapshots: poolSnapshots, isLoading: poolIsLoading, snapshotKey: `${type}_apy` as const }
}
return { snapshots: showMintGraph ? mintSnapshots : null, isLoading: mintIsLoading, snapshotKey: 'rate' as const }
}

/**
* Line graph cell that displays the average historical APY for a vault and a given type (borrow or lend).
*/
export const LineGraphCell = ({ market, type, showChart }: LineGraphCellProps) => {
const { snapshots, snapshotKey, isLoading } = useSnapshots(market, type)
const currentValue = market.rates[type]
const rate = useMemo(
() => (snapshots?.length ? meanBy(snapshots, (row) => row[snapshotKey]) : currentValue),
[snapshots, currentValue, snapshotKey],
)
const { design } = useTheme()
if (rate == null) {
return '-'
}
Expand All @@ -75,7 +79,7 @@ export const LineGraphCell = ({
<Line
type="monotone"
dataKey={snapshotKey}
stroke={getColor(design, snapshots, type)}
stroke={getColor(design, snapshots, snapshotKey)}
strokeWidth={1}
dot={<></>}
/>
Expand Down
17 changes: 10 additions & 7 deletions apps/main/src/loan/entities/crvusd.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PoolParams, PoolQuery, queryFactory, rootKeys } from '@ui-kit/lib/model/query'
import { poolValidationSuite } from '@ui-kit/lib/model/query/pool-validation'
import { ContractParams, PoolParams, PoolQuery, queryFactory, rootKeys } from '@ui-kit/lib/model/query'
import { contractValidationSuite } from '@ui-kit/lib/model/query/contract-validation'

type CrvUsdSnapshotFromApi = {
rate: number
Expand Down Expand Up @@ -35,19 +35,22 @@ type CrvUsdSnapshotsFromApi = {
data: CrvUsdSnapshotFromApi[]
}

export const _getCrvUsdSnapshots = async ({ chainId, poolId }: PoolQuery): Promise<CrvUsdSnapshotsFromApi> => {
const url = `https://prices.curve.fi/v1/crvusd/markets/${chainId}/${poolId}/snapshots`
export const _getCrvUsdSnapshots = async ({
blockchainId,
contractAddress,
}: ContractParams): Promise<CrvUsdSnapshotFromApi[]> => {
const url = `https://prices.curve.fi/v1/crvusd/markets/${blockchainId}/${contractAddress}/snapshots`
const response = await fetch(url)
const { data } = (await response.json()) as { data?: CrvUsdSnapshotsFromApi }
const { data } = (await response.json()) as CrvUsdSnapshotsFromApi
if (!data) {
throw new Error('Failed to fetch crvUSD snapshots')
}
return data
}

export const { useQuery: useCrvUsdSnapshots } = queryFactory({
queryKey: (params: PoolParams) => [...rootKeys.pool(params), 'crvUsdSnapshots'] as const,
queryKey: (params: ContractParams) => [...rootKeys.contract(params), 'crvUsd', 'snapshots'] as const,
queryFn: _getCrvUsdSnapshots,
staleTime: '1d',
validationSuite: poolValidationSuite,
validationSuite: contractValidationSuite,
})
1 change: 1 addition & 0 deletions apps/main/src/loan/entities/lending-vaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type AssetDetails = {
symbol: string
decimals?: number
address: string
blockchainId: string
usdPrice: number | null
}

Expand Down
19 changes: 13 additions & 6 deletions apps/main/src/loan/entities/llama-markets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Assets, getLendingVaultOptions, LendingVaultFromApi } from '@/loan/enti
import { useQueries } from '@tanstack/react-query'
import { getMintMarketOptions, MintMarketFromApi } from '@/loan/entities/mint-markets'
import { combineQueriesMeta, PartialQueryResult } from '@ui-kit/lib'
import useStore from '@/loan/store/useStore'

export enum LlamaMarketType {
Mint = 'mint',
Expand All @@ -19,7 +20,7 @@ export type LlamaMarket = {
usdTotal: number
}
rates: {
lend: number // apy %
lend?: number // apy %
borrow: number // apy %
}
type: LlamaMarketType
Expand Down Expand Up @@ -55,31 +56,37 @@ const convertMintMarket = (
llamma,
rate,
total_debt,
borrowable,
debt_ceiling,
collateral_amount,
collateral_amount_usd,
stablecoin_amount,
}: MintMarketFromApi,
blockchainId: string,
): LlamaMarket => ({
blockchainId,
address,
controllerAddress: llamma,
assets: {
borrowed: { symbol: stablecoin_token.symbol, address, usdPrice: stablecoin_amount / total_debt },
borrowed: {
symbol: stablecoin_token.symbol,
address: stablecoin_token.address,
// todo: get rate from the API
usdPrice: Number(useStore.getState().usdRates.tokens[stablecoin_token.address] ?? 1),
blockchainId,
},
collateral: {
symbol: collateral_token.symbol,
address: collateral_token.address,
usdPrice: collateral_amount_usd / collateral_amount,
blockchainId,
},
},
utilizationPercent: total_debt / borrowable,
utilizationPercent: (100 * total_debt) / debt_ceiling,
totalSupplied: {
// todo: do we want to see collateral or borrowable?
total: collateral_amount,
usdTotal: collateral_amount_usd,
},
rates: {
lend: rate * 100,
borrow: rate * 100,
},
type: LlamaMarketType.Mint,
Expand Down

0 comments on commit daef206

Please sign in to comment.