use apy; add borrow capacity calcs
This commit is contained in:
parent
0ae1642d8b
commit
71646b1d6d
|
@ -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>
|
||||
</>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
%
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
Loading…
Reference in New Issue