From bec6fd77a782ef453eb5175771f4db2bd1643507 Mon Sep 17 00:00:00 2001 From: cuzz-venus Date: Wed, 2 Sep 2026 15:54:58 +0800 Subject: [PATCH] feat: replace the hub contract row with the operator address Co-Authored-By: Claude Opus 5 --- .changeset/lucky-pugs-jump.md | 5 ++ apps/evm/src/clients/api/__mocks__/index.ts | 11 +++ apps/evm/src/clients/api/index.ts | 3 + .../__snapshots__/index.spec.ts.snap | 7 ++ .../__tests__/index.spec.ts | 28 ++++++++ .../getLiquidityHubOperatorAddress/index.ts | 28 ++++++++ .../__tests__/index.spec.ts | 62 ++++++++++++++++ .../index.ts | 38 ++++++++++ apps/evm/src/constants/functionKey.ts | 1 + .../libs/translations/translations/en.json | 2 +- .../libs/translations/translations/ja.json | 2 +- .../libs/translations/translations/th.json | 2 +- .../libs/translations/translations/tr.json | 2 +- .../libs/translations/translations/vi.json | 2 +- .../translations/translations/zh-Hans.json | 2 +- .../translations/translations/zh-Hant.json | 2 +- .../LiquidityHubInfo/__tests__/index.spec.tsx | 71 +++++++++++++++++++ .../LiquidityHub/LiquidityHubInfo/index.tsx | 19 +++-- .../__snapshots__/index.spec.tsx.snap | 2 +- 19 files changed, 274 insertions(+), 15 deletions(-) create mode 100644 .changeset/lucky-pugs-jump.md create mode 100644 apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/__tests__/__snapshots__/index.spec.ts.snap create mode 100644 apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/__tests__/index.spec.ts create mode 100644 apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/index.ts create mode 100644 apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/useGetLiquidityHubOperatorAddress/__tests__/index.spec.ts create mode 100644 apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/useGetLiquidityHubOperatorAddress/index.ts create mode 100644 apps/evm/src/pages/LiquidityHub/LiquidityHubInfo/__tests__/index.spec.tsx diff --git a/.changeset/lucky-pugs-jump.md b/.changeset/lucky-pugs-jump.md new file mode 100644 index 0000000000..5fbea1de23 --- /dev/null +++ b/.changeset/lucky-pugs-jump.md @@ -0,0 +1,5 @@ +--- +"@venusprotocol/evm": minor +--- + +Replace the Hub contract row with the operator address in the Liquidity Hub info section diff --git a/apps/evm/src/clients/api/__mocks__/index.ts b/apps/evm/src/clients/api/__mocks__/index.ts index 6e9c58d100..c6af097aa8 100644 --- a/apps/evm/src/clients/api/__mocks__/index.ts +++ b/apps/evm/src/clients/api/__mocks__/index.ts @@ -299,6 +299,17 @@ export const useGetLiquidityHubHistory = vi.fn(() => ({ }, })); +export const getLiquidityHubOperatorAddress = vi.fn(async () => ({ + operatorAddress: fakeAddress, +})); + +export const useGetLiquidityHubOperatorAddress = vi.fn(() => ({ + isLoading: false, + data: { + operatorAddress: fakeAddress, + }, +})); + export const useGetSimulatedPool = vi.fn(() => ({ isLoading: false, data: { diff --git a/apps/evm/src/clients/api/index.ts b/apps/evm/src/clients/api/index.ts index 770b74600e..5da5bfbd24 100644 --- a/apps/evm/src/clients/api/index.ts +++ b/apps/evm/src/clients/api/index.ts @@ -108,6 +108,9 @@ export * from './queries/getLiquidityHub/useGetLiquidityHub'; export * from './queries/getLiquidityHubHistory'; export * from './queries/getLiquidityHubHistory/useGetLiquidityHubHistory'; +export * from './queries/getLiquidityHubOperatorAddress'; +export * from './queries/getLiquidityHubOperatorAddress/useGetLiquidityHubOperatorAddress'; + export * from './queries/getMarketHistory'; export * from './queries/getMarketHistory/useGetMarketHistory'; diff --git a/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/__tests__/__snapshots__/index.spec.ts.snap b/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/__tests__/__snapshots__/index.spec.ts.snap new file mode 100644 index 0000000000..f97a90250e --- /dev/null +++ b/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/__tests__/__snapshots__/index.spec.ts.snap @@ -0,0 +1,7 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`getLiquidityHubOperatorAddress > returns the operator address in the right format on success 1`] = ` +{ + "operatorAddress": "0x3d759121234cd36F8124C21aFe1c6852d2bEd848", +} +`; diff --git a/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/__tests__/index.spec.ts b/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/__tests__/index.spec.ts new file mode 100644 index 0000000000..6e83d1f6c6 --- /dev/null +++ b/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/__tests__/index.spec.ts @@ -0,0 +1,28 @@ +import type { PublicClient } from 'viem'; + +import fakeAddress from '__mocks__/models/address'; +import { liquidityHubAbi } from 'libs/contracts'; + +import { getLiquidityHubOperatorAddress } from '..'; + +describe('getLiquidityHubOperatorAddress', () => { + it('returns the operator address in the right format on success', async () => { + const readContractMock = vi.fn().mockResolvedValue(fakeAddress); + + const fakePublicClient = { + readContract: readContractMock, + } as unknown as PublicClient; + + const res = await getLiquidityHubOperatorAddress({ + publicClient: fakePublicClient, + vhTokenAddress: fakeAddress, + }); + + expect(readContractMock).toHaveBeenCalledWith({ + address: fakeAddress, + abi: liquidityHubAbi, + functionName: 'owner', + }); + expect(res).toMatchSnapshot(); + }); +}); diff --git a/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/index.ts b/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/index.ts new file mode 100644 index 0000000000..c4b6d80cc8 --- /dev/null +++ b/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/index.ts @@ -0,0 +1,28 @@ +import { liquidityHubAbi } from 'libs/contracts'; +import type { Address, PublicClient } from 'viem'; + +export interface GetLiquidityHubOperatorAddressInput { + publicClient: PublicClient; + vhTokenAddress: Address; +} + +export type GetLiquidityHubOperatorAddressOutput = { + operatorAddress: Address; +}; + +export const getLiquidityHubOperatorAddress = async ({ + publicClient, + vhTokenAddress, +}: GetLiquidityHubOperatorAddressInput): Promise => { + // The hub exposes no operator getter: it is owned by the Venus DAO timelock, which is the + // entity operating it + const operatorAddress = await publicClient.readContract({ + address: vhTokenAddress, + abi: liquidityHubAbi, + functionName: 'owner', + }); + + return { + operatorAddress, + }; +}; diff --git a/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/useGetLiquidityHubOperatorAddress/__tests__/index.spec.ts b/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/useGetLiquidityHubOperatorAddress/__tests__/index.spec.ts new file mode 100644 index 0000000000..78b92b4237 --- /dev/null +++ b/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/useGetLiquidityHubOperatorAddress/__tests__/index.spec.ts @@ -0,0 +1,62 @@ +import { QueryClient } from '@tanstack/react-query'; +import { waitFor } from '@testing-library/react'; +import fakeAddress, { altAddress } from '__mocks__/models/address'; +import FunctionKey from 'constants/functionKey'; +import { usePublicClient } from 'libs/wallet'; +import { renderHook } from 'testUtils/render'; +import { ChainId } from 'types'; +import type { Address } from 'viem'; +import type { Mock } from 'vitest'; +import { useGetLiquidityHubOperatorAddress } from '..'; +import * as getLiquidityHubOperatorAddressQueries from '../..'; + +describe('useGetLiquidityHubOperatorAddress', () => { + it('uses the expected query key and calls getLiquidityHubOperatorAddress with the right parameters', async () => { + const fakePublicClient = { + readContract: vi.fn(), + }; + + const fakeOutput = { + operatorAddress: altAddress as Address, + }; + + const getLiquidityHubOperatorAddressSpy = vi + .spyOn(getLiquidityHubOperatorAddressQueries, 'getLiquidityHubOperatorAddress') + .mockResolvedValue(fakeOutput); + + (usePublicClient as Mock).mockImplementation(() => ({ + publicClient: fakePublicClient, + })); + + const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + gcTime: 0, + }, + }, + }); + + const { result } = renderHook( + () => useGetLiquidityHubOperatorAddress({ vhTokenAddress: fakeAddress }), + { + chainId: ChainId.BSC_MAINNET, + queryClient, + }, + ); + + await waitFor(() => expect(result.current.isSuccess).toBe(true)); + + expect(getLiquidityHubOperatorAddressSpy).toHaveBeenCalledWith({ + publicClient: fakePublicClient, + vhTokenAddress: fakeAddress, + }); + + expect( + queryClient.getQueryData([ + FunctionKey.GET_LIQUIDITY_HUB_OPERATOR_ADDRESS, + { chainId: ChainId.BSC_MAINNET, vhTokenAddress: fakeAddress }, + ]), + ).toEqual(fakeOutput); + }); +}); diff --git a/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/useGetLiquidityHubOperatorAddress/index.ts b/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/useGetLiquidityHubOperatorAddress/index.ts new file mode 100644 index 0000000000..d440621edf --- /dev/null +++ b/apps/evm/src/clients/api/queries/getLiquidityHubOperatorAddress/useGetLiquidityHubOperatorAddress/index.ts @@ -0,0 +1,38 @@ +import { type QueryObserverOptions, useQuery } from '@tanstack/react-query'; + +import FunctionKey from 'constants/functionKey'; +import { useChainId, usePublicClient } from 'libs/wallet'; +import type { ChainId } from 'types'; +import type { Address } from 'viem'; +import { type GetLiquidityHubOperatorAddressOutput, getLiquidityHubOperatorAddress } from '..'; + +export type UseGetLiquidityHubOperatorAddressInput = { + vhTokenAddress: Address; +}; + +export type UseGetLiquidityHubOperatorAddressQueryKey = [ + FunctionKey.GET_LIQUIDITY_HUB_OPERATOR_ADDRESS, + { chainId: ChainId; vhTokenAddress: Address }, +]; + +type Options = QueryObserverOptions< + GetLiquidityHubOperatorAddressOutput, + Error, + GetLiquidityHubOperatorAddressOutput, + GetLiquidityHubOperatorAddressOutput, + UseGetLiquidityHubOperatorAddressQueryKey +>; + +export const useGetLiquidityHubOperatorAddress = ( + { vhTokenAddress }: UseGetLiquidityHubOperatorAddressInput, + options?: Partial, +) => { + const { chainId } = useChainId(); + const { publicClient } = usePublicClient(); + + return useQuery({ + queryKey: [FunctionKey.GET_LIQUIDITY_HUB_OPERATOR_ADDRESS, { chainId, vhTokenAddress }], + queryFn: () => getLiquidityHubOperatorAddress({ publicClient, vhTokenAddress }), + ...options, + }); +}; diff --git a/apps/evm/src/constants/functionKey.ts b/apps/evm/src/constants/functionKey.ts index 9434725493..07aef1318a 100644 --- a/apps/evm/src/constants/functionKey.ts +++ b/apps/evm/src/constants/functionKey.ts @@ -83,6 +83,7 @@ enum FunctionKey { GET_HAS_ISOLATED_POOL_POSITION = 'GET_HAS_ISOLATED_POOL_POSITION', GET_LIQUIDITY_HUB = 'GET_LIQUIDITY_HUB', GET_LIQUIDITY_HUB_HISTORY = 'GET_LIQUIDITY_HUB_HISTORY', + GET_LIQUIDITY_HUB_OPERATOR_ADDRESS = 'GET_LIQUIDITY_HUB_OPERATOR_ADDRESS', GET_ADDRESS_DOMAIN_NAME = 'GET_ADDRESS_DOMAIN_NAME', GET_BURNED_BNB = 'GET_BURNED_BNB', GET_IMPORTABLE_POSITIONS = 'GET_IMPORTABLE_POSITIONS', diff --git a/apps/evm/src/libs/translations/translations/en.json b/apps/evm/src/libs/translations/translations/en.json index 6b86147cee..8d8419e7eb 100644 --- a/apps/evm/src/libs/translations/translations/en.json +++ b/apps/evm/src/libs/translations/translations/en.json @@ -991,8 +991,8 @@ "title": "Exchange rate", "value": "1 {{vhTokenSymbol}} = {{ exchangeRate }} {{ underlyingTokenSymbol }}" }, - "hubContract": "Hub contract", "operator": "Operator", + "operatorAddress": "Operator address", "operatorName": "Venus DAO", "performanceFee": "Performance fee", "redeemFee": "Redeem fee", diff --git a/apps/evm/src/libs/translations/translations/ja.json b/apps/evm/src/libs/translations/translations/ja.json index 87684d784b..64b608ec7a 100644 --- a/apps/evm/src/libs/translations/translations/ja.json +++ b/apps/evm/src/libs/translations/translations/ja.json @@ -990,8 +990,8 @@ "title": "交換レート", "value": "1 {{vhTokenSymbol}} = {{ exchangeRate }} {{ underlyingTokenSymbol }}" }, - "hubContract": "ハブコントラクト", "operator": "オペレーター", + "operatorAddress": "TRANSLATION NEEDED", "operatorName": "Venus DAO", "performanceFee": "パフォーマンス手数料", "redeemFee": "償還手数料", diff --git a/apps/evm/src/libs/translations/translations/th.json b/apps/evm/src/libs/translations/translations/th.json index aa4359b426..8b90ca8bf8 100644 --- a/apps/evm/src/libs/translations/translations/th.json +++ b/apps/evm/src/libs/translations/translations/th.json @@ -990,8 +990,8 @@ "title": "อัตราแลกเปลี่ยน", "value": "1 {{vhTokenSymbol}} = {{ exchangeRate }} {{ underlyingTokenSymbol }}" }, - "hubContract": "สัญญาศูนย์", "operator": "ผู้ดำเนินการ", + "operatorAddress": "TRANSLATION NEEDED", "operatorName": "Venus DAO", "performanceFee": "ค่าธรรมเนียมผลการดำเนินงาน", "redeemFee": "ค่าธรรมเนียมไถ่ถอน", diff --git a/apps/evm/src/libs/translations/translations/tr.json b/apps/evm/src/libs/translations/translations/tr.json index f3842fc390..8d383ba1a2 100644 --- a/apps/evm/src/libs/translations/translations/tr.json +++ b/apps/evm/src/libs/translations/translations/tr.json @@ -991,8 +991,8 @@ "title": "Döviz kuru", "value": "1 {{vhTokenSymbol}} = {{ exchangeRate }} {{ underlyingTokenSymbol }}" }, - "hubContract": "Merkez sözleşmesi", "operator": "Operatör", + "operatorAddress": "TRANSLATION NEEDED", "operatorName": "Venus DAO", "performanceFee": "Performans ücreti", "redeemFee": "İtfa ücreti", diff --git a/apps/evm/src/libs/translations/translations/vi.json b/apps/evm/src/libs/translations/translations/vi.json index ac1f1dc262..0bf9c42b20 100644 --- a/apps/evm/src/libs/translations/translations/vi.json +++ b/apps/evm/src/libs/translations/translations/vi.json @@ -990,8 +990,8 @@ "title": "Tỷ giá hối đoái", "value": "1 {{vhTokenSymbol}} = {{ exchangeRate }} {{ underlyingTokenSymbol }}" }, - "hubContract": "Hợp đồng hub", "operator": "Nhà vận hành", + "operatorAddress": "TRANSLATION NEEDED", "operatorName": "Venus DAO", "performanceFee": "Phí hiệu suất", "redeemFee": "Phí đổi lại", diff --git a/apps/evm/src/libs/translations/translations/zh-Hans.json b/apps/evm/src/libs/translations/translations/zh-Hans.json index f5007a0781..0297975128 100644 --- a/apps/evm/src/libs/translations/translations/zh-Hans.json +++ b/apps/evm/src/libs/translations/translations/zh-Hans.json @@ -990,8 +990,8 @@ "title": "汇率", "value": "1 {{vhTokenSymbol}} = {{ exchangeRate }} {{ underlyingTokenSymbol }}" }, - "hubContract": "中心合约", "operator": "运营方", + "operatorAddress": "TRANSLATION NEEDED", "operatorName": "Venus DAO", "performanceFee": "绩效费", "redeemFee": "赎回费", diff --git a/apps/evm/src/libs/translations/translations/zh-Hant.json b/apps/evm/src/libs/translations/translations/zh-Hant.json index 4aef1828e0..4f85af8cda 100644 --- a/apps/evm/src/libs/translations/translations/zh-Hant.json +++ b/apps/evm/src/libs/translations/translations/zh-Hant.json @@ -990,8 +990,8 @@ "title": "匯率", "value": "1 {{vhTokenSymbol}} = {{ exchangeRate }} {{ underlyingTokenSymbol }}" }, - "hubContract": "中心合約", "operator": "營運方", + "operatorAddress": "TRANSLATION NEEDED", "operatorName": "Venus DAO", "performanceFee": "績效費", "redeemFee": "贖回費", diff --git a/apps/evm/src/pages/LiquidityHub/LiquidityHubInfo/__tests__/index.spec.tsx b/apps/evm/src/pages/LiquidityHub/LiquidityHubInfo/__tests__/index.spec.tsx new file mode 100644 index 0000000000..9d6bbb33b3 --- /dev/null +++ b/apps/evm/src/pages/LiquidityHub/LiquidityHubInfo/__tests__/index.spec.tsx @@ -0,0 +1,71 @@ +import { screen } from '@testing-library/react'; +import type { Mock } from 'vitest'; + +import fakeAddress from '__mocks__/models/address'; +import { liquidityHubs } from '__mocks__/models/liquidityHubs'; +import { useGetLiquidityHubOperatorAddress } from 'clients/api'; +import { PLACEHOLDER_KEY } from 'constants/placeholders'; +import { en } from 'libs/translations'; +import { renderComponent } from 'testUtils/render'; +import { ChainId } from 'types'; +import { generateExplorerUrl, truncateAddress } from 'utilities'; +import { LiquidityHubInfo } from '..'; + +const liquidityHub = liquidityHubs[0]; + +const renderLiquidityHubInfo = () => + renderComponent(, { + chainId: ChainId.BSC_TESTNET, + }); + +describe('LiquidityHubInfo', () => { + const mockUseGetLiquidityHubOperatorAddress = useGetLiquidityHubOperatorAddress as Mock; + + it('renders the operator address, linking to the chain explorer', () => { + renderLiquidityHubInfo(); + + expect(mockUseGetLiquidityHubOperatorAddress).toHaveBeenCalledWith({ + vhTokenAddress: liquidityHub.vhToken.address, + }); + expect(screen.getByText(en.liquidityHub.info.stats.operatorAddress)).toBeInTheDocument(); + expect(screen.getByText(truncateAddress(fakeAddress))).toBeInTheDocument(); + + const operatorAddressLink = screen + .getByText(truncateAddress(fakeAddress)) + .closest('a') as HTMLAnchorElement; + + expect(operatorAddressLink).toHaveAttribute( + 'href', + generateExplorerUrl({ hash: fakeAddress, chainId: ChainId.BSC_TESTNET }), + ); + }); + + it('does not render the hub contract row anymore', () => { + renderLiquidityHubInfo(); + + // The hub contract address is identical to the vhToken contract address, so the only remaining + // row displaying it is the vhToken one + expect(screen.getAllByText(truncateAddress(liquidityHub.vhToken.address)).length).toBe(1); + expect( + screen.getByText( + en.liquidityHub.info.stats.vhTokenContract.replace( + '{{ vhTokenSymbol }}', + liquidityHub.vhToken.symbol, + ), + ), + ).toBeInTheDocument(); + }); + + it('renders a placeholder while the operator address has not been fetched', () => { + mockUseGetLiquidityHubOperatorAddress.mockReturnValue({ + isLoading: true, + data: undefined, + }); + + renderLiquidityHubInfo(); + + expect(screen.getByText(en.liquidityHub.info.stats.operatorAddress)).toBeInTheDocument(); + expect(screen.getByText(PLACEHOLDER_KEY)).toBeInTheDocument(); + expect(screen.queryByText(truncateAddress(fakeAddress))).toBeNull(); + }); +}); diff --git a/apps/evm/src/pages/LiquidityHub/LiquidityHubInfo/index.tsx b/apps/evm/src/pages/LiquidityHub/LiquidityHubInfo/index.tsx index c3ec500a53..6106b0c407 100644 --- a/apps/evm/src/pages/LiquidityHub/LiquidityHubInfo/index.tsx +++ b/apps/evm/src/pages/LiquidityHub/LiquidityHubInfo/index.tsx @@ -1,6 +1,8 @@ import { cn } from '@venusprotocol/ui'; +import { useGetLiquidityHubOperatorAddress } from 'clients/api'; import { MarketInfo, type MarketInfoProps } from 'components'; +import { PLACEHOLDER_KEY } from 'constants/placeholders'; import { routes } from 'constants/routing'; import { DAYS_PER_YEAR } from 'constants/time'; import { ChainExplorerLink } from 'containers/ChainExplorerLink'; @@ -22,6 +24,11 @@ export const LiquidityHubInfo: React.FC = ({ liquidityHub const { t, Trans } = useTranslation(); const { chainId } = useChainId(); + const { data: getLiquidityHubOperatorAddressData } = useGetLiquidityHubOperatorAddress({ + vhTokenAddress: liquidityHub.vhToken.address, + }); + const operatorAddress = getLiquidityHubOperatorAddressData?.operatorAddress; + const { totalApyPercentage } = getCombinedApy({ type: 'supply', baseApyPercentage: liquidityHub.supplyApyPercentage, @@ -41,13 +48,11 @@ export const LiquidityHubInfo: React.FC = ({ liquidityHub children: t('liquidityHub.info.stats.operatorName'), }, { - label: t('liquidityHub.info.stats.hubContract'), - children: ( - + label: t('liquidityHub.info.stats.operatorAddress'), + children: operatorAddress ? ( + + ) : ( + PLACEHOLDER_KEY ), }, { diff --git a/apps/evm/src/pages/LiquidityHub/__tests__/__snapshots__/index.spec.tsx.snap b/apps/evm/src/pages/LiquidityHub/__tests__/__snapshots__/index.spec.tsx.snap index 352f5b4af2..21f3aa3724 100644 --- a/apps/evm/src/pages/LiquidityHub/__tests__/__snapshots__/index.spec.tsx.snap +++ b/apps/evm/src/pages/LiquidityHub/__tests__/__snapshots__/index.spec.tsx.snap @@ -1,3 +1,3 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`LiquidityHub > loads the liquidity hub from the route and renders its content 1`] = `"SupplyWithdrawWalletCollateralXVSMAXSupply APY6.2%Distribution APY1.2%Total supply APY7.4%Connect walletSupply info61%Total supplied$109.03K / $178.75K15.25K / 25K XVSAverage APY4.1%Current APY7.4%Position unit price (vhXVS)1.06Allocation detailsVenus CoreAlloc.$8KLiquidity$6.2KAPY5.7%Cap55%Eff. cap$16KVenus FluxAlloc.$7.25KLiquidity$5.8KAPY6.8%Cap45%Eff. cap$14.5KSourceAlloc.sorted descendingLiquidityAPYCapEff. capVenus Core$8K$6.2K5.7%55%$16KVenus Flux$7.25K$5.8K6.8%45%$14.5KSort byAlloc.Venus CoreAlloc.$8KLiquidity$6.2KAPY5.7%Cap55%Eff. cap$16KVenus FluxAlloc.$7.25KLiquidity$5.8KAPY6.8%Cap45%Eff. cap$14.5KHub infoOperatorVenus DAOHub contract0x20...0001vhXVS contract0x20...0001Performance fee10%Redeem fee1%Daily supplying interests$22.1Exchange rate1 vhXVS = 1.06 XVSRisk disclosuresBy supplying to, withdrawing from, or otherwise interacting with the Venus Liquidity Hub, you acknowledge and agree that:You are interacting with autonomous smart contracts. Venus and its affiliates do not guarantee the performance, security, or availability of the Liquidity Hub or any related software, smart contracts, blockchain networks, or third-party integrations.Supplying assets to the Liquidity Hub does not grant borrowing power and does not constitute a deposit, loan, or investment product. You may not be able to withdraw at all times, and returns, if any, are not guaranteed.You assume all risks associated with your use of the Liquidity Hub and are solely responsible for determining whether it is appropriate for your financial circumstances, risk tolerance, and technical capabilities. You are responsible for conducting your own independent evaluation, including reviewing the relevant source code and on-chain configuration.Venus is a technology provider only and does not provide investment, advisory, fiduciary, or custodial services, and does not manage or hold your assets.Your interaction with the Liquidity Hub is governed by the Terms of Use."`; +exports[`LiquidityHub > loads the liquidity hub from the route and renders its content 1`] = `"SupplyWithdrawWalletCollateralXVSMAXSupply APY6.2%Distribution APY1.2%Total supply APY7.4%Connect walletSupply info61%Total supplied$109.03K / $178.75K15.25K / 25K XVSAverage APY4.1%Current APY7.4%Position unit price (vhXVS)1.06Allocation detailsVenus CoreAlloc.$8KLiquidity$6.2KAPY5.7%Cap55%Eff. cap$16KVenus FluxAlloc.$7.25KLiquidity$5.8KAPY6.8%Cap45%Eff. cap$14.5KSourceAlloc.sorted descendingLiquidityAPYCapEff. capVenus Core$8K$6.2K5.7%55%$16KVenus Flux$7.25K$5.8K6.8%45%$14.5KSort byAlloc.Venus CoreAlloc.$8KLiquidity$6.2KAPY5.7%Cap55%Eff. cap$16KVenus FluxAlloc.$7.25KLiquidity$5.8KAPY6.8%Cap45%Eff. cap$14.5KHub infoOperatorVenus DAOOperator address0x3d...d848vhXVS contract0x20...0001Performance fee10%Redeem fee1%Daily supplying interests$22.1Exchange rate1 vhXVS = 1.06 XVSRisk disclosuresBy supplying to, withdrawing from, or otherwise interacting with the Venus Liquidity Hub, you acknowledge and agree that:You are interacting with autonomous smart contracts. Venus and its affiliates do not guarantee the performance, security, or availability of the Liquidity Hub or any related software, smart contracts, blockchain networks, or third-party integrations.Supplying assets to the Liquidity Hub does not grant borrowing power and does not constitute a deposit, loan, or investment product. You may not be able to withdraw at all times, and returns, if any, are not guaranteed.You assume all risks associated with your use of the Liquidity Hub and are solely responsible for determining whether it is appropriate for your financial circumstances, risk tolerance, and technical capabilities. You are responsible for conducting your own independent evaluation, including reviewing the relevant source code and on-chain configuration.Venus is a technology provider only and does not provide investment, advisory, fiduciary, or custodial services, and does not manage or hold your assets.Your interaction with the Liquidity Hub is governed by the Terms of Use."`;