mars-v2-frontend/hooks/useAccountStats.tsx
Gustavo Mauricio bbbdca6950
MP-1227: Borrow Page (#24)
* added icon for atom and tokenInfo data update

* borrow page initial commit

* feat: borrow funds to ca and wallet

* close borrow module on tx success

* feat: repay funds initial setup

* repay funds action hook

* repay slider. module state on borrow page component

* styling: minor tweak to text colors

* limit manual input on repay to max value

* borrow funds component slider initial

* style: max button typography

* AssetRow extracted to separate file. organize imports

* ContainerSecondary component added

* loading indicator for pending actions

* style: progress bar colors

* tanstack table added

* tanstack react-table dependency missing

* table cleanup and layout adjustments

* fix account stats formula and update market data to match spreadsheet

* calculate max borrow amount hook

* reset borrow and repay components on account change

* max borrow amount decimals. memorized return

* hook tanstack data with real data

* redefine borrowedAssetsMap to map

* update max borrow amount formulas

* remove unnecessary table component. refactor borrow table
2022-10-20 16:39:21 +01:00

87 lines
2.8 KiB
TypeScript

import { useMemo } from 'react'
import BigNumber from 'bignumber.js'
import useCreditManagerStore from 'stores/useCreditManagerStore'
import { getTokenDecimals } from 'utils/tokens'
import useCreditAccountPositions from './useCreditAccountPositions'
import useMarkets from './useMarkets'
import useTokenPrices from './useTokenPrices'
// displaying 3 levels of risk based on the weighted average of liquidation LTVs
// 0.85 -> 25% risk
// 0.65 - 0.85 -> 50% risk
// < 0.65 -> 100% risk
const getRiskFromAverageLiquidationLTVs = (value: number) => {
if (value >= 0.85) return 0.25
if (value > 0.65) return 0.5
return 1
}
const useAccountStats = () => {
const selectedAccount = useCreditManagerStore((s) => s.selectedAccount)
const { data: positionsData } = useCreditAccountPositions(selectedAccount ?? '')
const { data: marketsData } = useMarkets()
const { data: tokenPrices } = useTokenPrices()
return useMemo(() => {
if (!marketsData || !tokenPrices || !positionsData) return null
const getTokenTotalUSDValue = (amount: string, denom: string) => {
// early return if prices are not fetched yet
if (!tokenPrices) return 0
return BigNumber(amount)
.div(10 ** getTokenDecimals(denom))
.times(tokenPrices[denom])
.toNumber()
}
const totalPosition = positionsData.coins.reduce((acc, coin) => {
const tokenTotalValue = getTokenTotalUSDValue(coin.amount, coin.denom)
return BigNumber(tokenTotalValue).plus(acc).toNumber()
}, 0)
const totalDebt = positionsData.debts.reduce((acc, coin) => {
const tokenTotalValue = getTokenTotalUSDValue(coin.amount, coin.denom)
return BigNumber(tokenTotalValue).plus(acc).toNumber()
}, 0)
const totalWeightedPositions = positionsData.coins.reduce((acc, coin) => {
const tokenWeightedValue = BigNumber(getTokenTotalUSDValue(coin.amount, coin.denom)).times(
Number(marketsData[coin.denom].liquidation_threshold)
)
return tokenWeightedValue.plus(acc).toNumber()
}, 0)
const netWorth = BigNumber(totalPosition).minus(totalDebt).toNumber()
const liquidationLTVsWeightedAverage = BigNumber(totalWeightedPositions)
.div(totalPosition)
.toNumber()
const maxLeverage = BigNumber(1)
.div(BigNumber(1).minus(liquidationLTVsWeightedAverage))
.toNumber()
const currentLeverage = BigNumber(totalPosition).div(netWorth).toNumber()
const health = BigNumber(1).minus(BigNumber(currentLeverage).div(maxLeverage)).toNumber() || 1
const risk = liquidationLTVsWeightedAverage
? getRiskFromAverageLiquidationLTVs(liquidationLTVsWeightedAverage)
: 0
return {
health,
maxLeverage,
currentLeverage,
netWorth,
risk,
totalPosition,
totalDebt,
}
}, [marketsData, positionsData, tokenPrices])
}
export default useAccountStats