use apy; add borrow capacity calcs

This commit is contained in:
tjs 2023-09-15 14:53:40 -04:00
parent 0ae1642d8b
commit 71646b1d6d
5 changed files with 84 additions and 32 deletions

View File

@ -1,13 +1,58 @@
import useStakeRates from 'hooks/useStakeRates'
import { formatTokenSymbol } from 'utils/tokens'
import SheenLoader from './shared/SheenLoader'
import { useMemo } from 'react'
import Decimal from 'decimal.js'
import useMangoGroup from 'hooks/useMangoGroup'
import FormatNumericValue from './shared/FormatNumericValue'
const AccountStats = ({ token }: { token: string }) => {
const { data: stakeRates, isLoading: loadingRates } = useStakeRates()
const { group } = useMangoGroup()
const solBank = useMemo(() => {
return group?.banksMapByName.get('SOL')?.[0]
}, [group, token])
const tokenBank = useMemo(() => {
return group?.banksMapByName.get(token)?.[0]
}, [group, token])
const solDeposits = useMemo(() => {
if (!solBank) return null
return solBank.uiDeposits()
}, [solBank])
const tokenDeposits = useMemo(() => {
if (!tokenBank) return null
return tokenBank.uiDeposits()
}, [tokenBank])
const solAvailable = useMemo(() => {
if (!solBank || !solDeposits) return 0
const availableVaultBalance = group
? group.getTokenVaultBalanceByMintUi(solBank.mint) -
solDeposits * solBank.minVaultToDepositsRatio
: 0
return Decimal.max(0, availableVaultBalance.toFixed(solBank.mintDecimals))
}, [solBank, solDeposits, group])
return (
<>
<h2 className="mb-4 text-2xl">{`Boosted ${formatTokenSymbol(token)}`}</h2>
<div className="grid grid-cols-2 gap-6 md:grid-cols-1">
<div>
<p className="mb-1">Est. APR</p>
<span className="text-2xl font-bold">14.89%</span>
<p className="mb-1">Max Est. APY</p>
<span className="text-2xl font-bold">
{loadingRates ? (
<SheenLoader className="mt-0.5">
<div className="h-5 w-10 bg-th-bkg-3" />
</SheenLoader>
) : stakeRates?.[token.toLowerCase()] ? (
`${(stakeRates?.[token.toLowerCase()] * 100).toFixed(2)}%`
) : null}
% SOL
</span>
</div>
<div>
<p className="mb-1">Max Leverage</p>
@ -15,11 +60,16 @@ const AccountStats = ({ token }: { token: string }) => {
</div>
<div>
<p className="mb-1">Capacity Remaining</p>
<span className="text-2xl font-bold">100,000 SOL</span>
<span className="text-2xl font-bold">
<FormatNumericValue value={solAvailable} decimals={0} /> SOL
</span>
</div>
<div>
<p className="mb-1">Total Staked</p>
<span className="text-2xl font-bold">{`100,000 ${token}`}</span>
<span className="text-2xl font-bold">
<FormatNumericValue value={tokenDeposits || 0} decimals={1} />{' '}
{token}
</span>
</div>
</div>
</>

View File

@ -107,7 +107,7 @@ const Positions = ({
</span>
</div>
<div>
<p className="mb-1">Est. APR</p>
<p className="mb-1">Est. APY</p>
<span className="text-xl font-bold">14.89%</span>
</div>
<div>

View File

@ -132,7 +132,7 @@ function DepositForm({ onSuccess, token: selectedToken }: DepositFormProps) {
if (!solPrice || !stakePrice || !Number(inputAmount)) return 0
const priceDifference = (stakePrice - solPrice) / solPrice
const borrowAmount =
(1 + priceDifference) * Number(inputAmount) * (leverage - 1)
(1 + priceDifference) * Number(inputAmount) * Math.min(leverage - 1, 1)
return borrowAmount
}, [leverage, solBank, stakeBank, inputAmount])
@ -339,7 +339,7 @@ function DepositForm({ onSuccess, token: selectedToken }: DepositFormProps) {
</div>
<div className="space-y-1.5 border-t border-th-bkg-3 px-2 pt-4">
<div className="flex justify-between">
<p>{selectedToken} Leveraged APR</p>
<p>{selectedToken} Leveraged APY</p>
<span className="text-th-fgd-1">
<FormatNumericValue
value={7.28 * leverage}
@ -362,7 +362,9 @@ function DepositForm({ onSuccess, token: selectedToken }: DepositFormProps) {
<p>SOL Borrow Rate</p>
<span className="text-th-fgd-1">
<FormatNumericValue
value={solBank.getDepositRateUi()}
value={
solBank.getDepositRateUi() * Math.min(leverage - 1, 1)
}
decimals={2}
/>
%

View File

@ -1,4 +1,4 @@
import useStakeApr from 'hooks/useStakeAprs'
import useStakeRates from 'hooks/useStakeRates'
import Image from 'next/image'
import { formatTokenSymbol } from 'utils/tokens'
import SheenLoader from './shared/SheenLoader'
@ -13,12 +13,12 @@ const TokenButton = ({
handleTokenSelect: (v: string) => void
}) => {
const {
data: stakeAprs,
isLoading: loadingStakeAprs,
isFetching: fetchingStakeAprs,
} = useStakeApr()
data: stakeRates,
isLoading: loadingStakeRates,
isFetching: fetchingStakeRates,
} = useStakeRates()
const loadingAprs = loadingStakeAprs || fetchingStakeAprs
const loadingRates = loadingStakeRates || fetchingStakeRates
return (
<button
@ -38,12 +38,12 @@ const TokenButton = ({
{formatTokenSymbol(tokenName)}
</span>
<span>
{loadingAprs ? (
{loadingRates ? (
<SheenLoader className="mt-0.5">
<div className="h-5 w-10 bg-th-bkg-3" />
</SheenLoader>
) : stakeAprs?.[tokenName.toLowerCase()] ? (
`${(stakeAprs?.[tokenName.toLowerCase()] * 100).toFixed(2)}%`
) : stakeRates?.[tokenName.toLowerCase()] ? (
`${(stakeRates?.[tokenName.toLowerCase()] * 100).toFixed(2)}%`
) : null}
</span>
</div>

View File

@ -7,7 +7,7 @@ import {
PERIOD,
} from '@glitchful-dev/sol-apy-sdk'
const fetchApr = async () => {
const fetchRates = async () => {
const [msolPrices, jitoPrices, bsolPrices, lidoPrices] = await Promise.all([
fetchAndParsePricesCsv(DATA_SOURCE.MARINADE_CSV),
fetchAndParsePricesCsv(DATA_SOURCE.JITO_CSV),
@ -17,34 +17,34 @@ const fetchApr = async () => {
console.log('jitosol', jitoPrices)
// may be null if the price range cannot be calculated
const msolRange = getPriceRangeFromPeriod(msolPrices, PERIOD.DAYS_14)
const jitoRange = getPriceRangeFromPeriod(jitoPrices, PERIOD.DAYS_14)
const bsolRange = getPriceRangeFromPeriod(bsolPrices, PERIOD.DAYS_14)
const lidoRange = getPriceRangeFromPeriod(lidoPrices, PERIOD.DAYS_14)
const msolRange = getPriceRangeFromPeriod(msolPrices, PERIOD.DAYS_7)
const jitoRange = getPriceRangeFromPeriod(jitoPrices, PERIOD.DAYS_7)
const bsolRange = getPriceRangeFromPeriod(bsolPrices, PERIOD.DAYS_7)
const lidoRange = getPriceRangeFromPeriod(lidoPrices, PERIOD.DAYS_7)
console.log('msol prices', msolPrices)
const aprData: Record<string, number> = {}
const rateData: Record<string, number> = {}
if (msolRange) {
console.log('APR: ', calcYield(msolRange)?.apr) // 0.06493501845986677 => 6.49 %
console.log('APY: ', calcYield(msolRange)?.apy) // 0.06707557862842384 => 6.71 %
aprData.msol = calcYield(msolRange)?.apr
rateData.msol = calcYield(msolRange)?.apy
}
if (jitoRange) {
aprData.jitosol = calcYield(jitoRange)?.apr
rateData.jitosol = calcYield(jitoRange)?.apy
}
if (bsolRange) {
aprData.bsol = calcYield(bsolRange)?.apr
rateData.bsol = calcYield(bsolRange)?.apy
}
if (lidoRange) {
aprData.stsol = calcYield(lidoRange)?.apr
rateData.stsol = calcYield(lidoRange)?.apy
}
return aprData
return rateData
}
fetchApr()
fetchRates()
export default function useStakeApr() {
const response = useQuery(['apr'], () => fetchApr(), {
export default function useStakeRates() {
const response = useQuery(['stake-rates'], () => fetchRates(), {
cacheTime: 1000 * 60 * 5,
staleTime: 1000 * 60,
retry: 3,