Mp 3245 usehlsvaults hook (#541)

*  routing and pages for HLS

*  create hooks for fetching HLS vaults and Strategies

* Share accounts (#539)

* feat: do not redirect to wallet on portfolio page

* fix: use connected wallet for AccountMenu

* fix: fixed ghost AccountDetails

* feat: created ShareBar and share functionality

* fix: don’t show shareBar if no address is present

* fix: stupid 'next/navigation'

* tidy: format

* fix: fixed tests

*  routing and pages for HLS (#538)

* 🐛 use useAccountIds

* fix: fixed the tests

* fix: accountIds is now a suspense

---------

Co-authored-by: Bob van der Helm <34470358+bobthebuidlr@users.noreply.github.com>

* 🐛 fix build

---------

Co-authored-by: Linkie Link <linkielink.dev@gmail.com>
This commit is contained in:
Bob van der Helm 2023-10-16 10:45:57 +02:00 committed by GitHub
parent 02d8d2147c
commit 5392a4717c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 152 additions and 1 deletions

View File

@ -0,0 +1,28 @@
import { getParamsQueryClient } from 'api/cosmwasm-client'
import getAssetParams from 'api/params/getAssetParams'
import { BN } from 'utils/helpers'
import { resolveHLSStrategies } from 'utils/resolvers'
export default async function getHLSStakingAssets() {
const assetParams = await getAssetParams()
const client = await getParamsQueryClient()
const HLSAssets = assetParams.filter((asset) => asset.credit_manager.hls)
const strategies = resolveHLSStrategies('coin', HLSAssets)
const depositCaps$ = strategies.map((strategy) =>
client.totalDeposit({ denom: strategy.denoms.deposit }),
)
return Promise.all(depositCaps$).then((depositCaps) => {
return depositCaps.map((depositCap, index) => {
return {
...strategies[index],
depositCap: {
denom: depositCap.denom,
used: BN(depositCap.amount),
max: BN(depositCap.cap),
},
} as HLSStrategy
})
})
}

View File

@ -0,0 +1,34 @@
import { getCreditManagerQueryClient } from 'api/cosmwasm-client'
import getAssetParams from 'api/params/getAssetParams'
import { getVaultConfigs } from 'api/vaults/getVaultConfigs'
import { BN } from 'utils/helpers'
import { resolveHLSStrategies } from 'utils/resolvers'
export default async function getHLSVaults() {
const assetParams = await getAssetParams()
const client = await getCreditManagerQueryClient()
const vaultConfigs = await getVaultConfigs()
const HLSAssets = assetParams.filter((asset) => asset.credit_manager.hls)
const strategies = resolveHLSStrategies('vault', HLSAssets)
const vaultUtilizations$ = strategies.map((strategy) =>
client.vaultUtilization({ vault: { address: strategy.denoms.deposit } }),
)
return Promise.all(vaultUtilizations$).then((vaultUtilizations) =>
vaultUtilizations.map(
(utilization, index) =>
({
...strategies[index],
depositCap: {
denom: utilization.vault.address,
used: BN(utilization.utilization.amount),
max: BN(
vaultConfigs.find((config) => config.addr === utilization.vault.address)?.deposit_cap
.amount || 0,
),
},
}) as HLSStrategy,
),
)
}

View File

@ -0,0 +1,3 @@
export default function AvailableHlsStakingAssets() {
return null
}

View File

@ -0,0 +1,3 @@
export default function AvailableHlsVaults() {
return null
}

View File

@ -0,0 +1,10 @@
import useSWR from 'swr'
import getHLSStakingAssets from 'api/hls/getHLSStakingAssets'
export default function useHLSStakingAssets() {
return useSWR('hls-staking', getHLSStakingAssets, {
fallbackData: [],
revalidateOnFocus: false,
})
}

10
src/hooks/useHLSVaults.ts Normal file
View File

@ -0,0 +1,10 @@
import useSWR from 'swr'
import getHLSVaults from 'api/hls/getHLSVaults'
export default function useHLSVaults() {
return useSWR('hls-vaults', getHLSVaults, {
fallbackData: [],
revalidateOnFocus: false,
})
}

View File

@ -1,4 +1,5 @@
import Tab from 'components/Earn/Tab'
import AvailableHLSVaults from 'components/HLS/AvailableHLSVaults'
import MigrationBanner from 'components/MigrationBanner'
import { HLS_TABS } from 'constants/pages'
@ -7,6 +8,7 @@ export default function HLSFarmPage() {
<div className='flex flex-wrap w-full gap-6'>
<MigrationBanner />
<Tab tabs={HLS_TABS} activeTabIdx={0} />
<AvailableHLSVaults />
</div>
)
}

View File

@ -1,4 +1,5 @@
import Tab from 'components/Earn/Tab'
import AvailableHlsStakingAssets from 'components/HLS/AvailableHLSStakingAssets'
import MigrationBanner from 'components/MigrationBanner'
import { HLS_TABS } from 'constants/pages'
@ -7,6 +8,7 @@ export default function HLSStakingPage() {
<div className='flex flex-wrap w-full gap-6'>
<MigrationBanner />
<Tab tabs={HLS_TABS} activeTabIdx={1} />
<AvailableHlsStakingAssets />
</div>
)
}

View File

@ -97,3 +97,17 @@ interface MarketTableData {
marketLiquidityAmount: BigNumber
marketLiquidationThreshold: number
}
interface HLSStrategy extends HLSStrategyNoCap {
depositCap: DepositCap
}
interface HLSStrategyNoCap {
maxLTV: number
maxLeverage: number
apy: number | null
denoms: {
deposit: string
borrow: string
}
}

View File

@ -56,3 +56,7 @@ export function getValueFromBNCoins(coins: BNCoin[], prices: BNCoin[]): BigNumbe
return totalValue
}
export function getLeverageFromLTV(ltv: number) {
return +(1 / (1 - ltv)).toPrecision(2)
}

View File

@ -1,9 +1,10 @@
import {
AssetParamsBaseForAddr as AssetParams,
AssetParamsBaseForAddr,
TotalDepositResponse,
} from 'types/generated/mars-params/MarsParams.types'
import { Market as RedBankMarket } from 'types/generated/mars-red-bank/MarsRedBank.types'
import { BN } from 'utils/helpers'
import { BN, getLeverageFromLTV } from 'utils/helpers'
export function resolveMarketResponse(
marketResponse: RedBankMarket,
@ -27,3 +28,43 @@ export function resolveMarketResponse(
liquidationThreshold: Number(assetParamsResponse.liquidation_threshold),
}
}
export function resolveHLSStrategies(
type: 'vault' | 'coin',
assets: AssetParamsBaseForAddr[],
): HLSStrategyNoCap[] {
const HLSStakingStrategies: HLSStrategyNoCap[] = []
assets.forEach((asset) => {
const correlations = asset.credit_manager.hls?.correlations.filter((correlation) => {
return type in correlation
})
let correlatedDenoms: string[] | undefined
if (type === 'coin') {
correlatedDenoms = correlations
?.map((correlation) => (correlation as { coin: { denom: string } }).coin.denom)
.filter((denoms) => !denoms.includes('gamm/pool/'))
} else {
correlatedDenoms = correlations?.map(
(correlation) => (correlation as { vault: { addr: string } }).vault.addr,
)
}
if (!correlatedDenoms?.length) return
correlatedDenoms.forEach((correlatedDenom) =>
HLSStakingStrategies.push({
apy: null,
maxLeverage: getLeverageFromLTV(+asset.credit_manager.hls!.max_loan_to_value),
maxLTV: +asset.credit_manager.hls!.max_loan_to_value,
denoms: {
deposit: correlatedDenom,
borrow: asset.denom,
},
}),
)
})
return HLSStakingStrategies
}