Liquidity Hub
The Venus Liquidity Hub is a per-asset ERC-4626 allocator vault. A lender deposits a single asset, the Hub routes it across Venus yield families (Core, Flux, FRV, Spoke and, on the USDT and USDC Hubs, Centrifuge) under a governance-set policy, and returns a yield-bearing share token. Yield accrues through a rising exchange rate (one share = X underlying), never by rebasing. There is one Hub per asset, with no cross-asset coupling.
For the user-facing introduction, see Liquidity Hub under What’s New.
Architecture
Section titled “Architecture”Routing is three-tiered. The Hub depends only on the IYieldGroupBase interface and never reaches past a Source into the underlying market.
- Hub — the ERC-4626 entry point (one beacon proxy per asset). Holds the Source registry, the two outer routing queues, dual caps, the per-transaction withdrawal cap, the fee parameters, and the multi-level pause flags. It exposes no APY view of its own — spot APY is read per-Source from
YieldGroup.spotAPYBps(), andHubLens.spotAPYBps(hub)is what blends those into one figure. - YieldGroup (Source) — aggregates one or more resources of a single protocol family behind the uniform
IYieldGroupBaseboundary, and owns its own inner deposit / withdraw queues and per-resource registry. - Adapter — a stateless singleton translating between a YieldGroup and one protocol ABI. Mutating calls run via delegatecall so receipt tokens land on the YieldGroup; one deployment per ABI family serves every YieldGroup.
- Resource — the underlying market or vault that holds the capital (a Venus Core vToken, a Fluid fToken, a Fixed-Rate Vault share, a spoke-pool vToken, or a Centrifuge fund vault).
Terminology. The PRD calls the grouping layer a Source; the code names the contract a YieldGroup and the Hub-facing interface
IYieldGroupBase. There is noISourcetype in the Solidity — “Source” survives only in deployment-artifact aliases (CoreSource_USDT,FluxSource_USDC,FRVSource_U). PRD Product / Vault = code Resource.
The yield families
Section titled “The yield families”| Core | Flux | FRV | Spoke | Centrifuge | |
|---|---|---|---|---|---|
| Underlying protocol | Venus Core lending | Fluid Lending | Venus Fixed-Rate Vaults | Venus hub-funded spoke pools | Centrifuge tokenized funds |
| Resource / receipt token | vToken (Compound-style) | fToken (ERC-4626 share) | FRV vault share (ERC-4626) | vToken (isolated-pools) | ERC-7540 vault share (JTRSY, JAAA) |
| Deposit / withdraw call | mint / redeemUnderlying | deposit / withdraw | deposit / withdraw | mint / redeem (by vToken count) | requestDeposit / requestRedeem, then claim |
| Spot APY source | supplyRatePerBlock × blocksPerYear | Fluid LendingResolver | vault fixedAPY net of reserveFactor (Fundraising / Lock) | supplyRatePerBlock × the market’s own blocksOrSecondsPerYear | published with setSpotAPYBps (governance, the Operator or the Guardian) |
| Who may supply | anyone | anyone | anyone | allowlisted only: the pool grants the YieldGroup address | only addresses on the fund’s own investor list |
| Valuation basis | balance × exchange rate | previewRedeem | lifecycle-aware linear accrual | balance × exchange rate, badDebt included | held shares and open requests (assets at face, shares at the vault’s share price), clamped to its NAV band |
| Lifecycle constraint | none | none | 11-state machine | none | asynchronous requests, settled by the fund manager |
| Wired at launch | ✅ vToken registered | ✅ fToken registered | ❌ Source registered, no resource | added later by VIP-669 and VIP-670, funding a live spoke pool | added later by VIP-661 and VIP-666, USDT and USDC Hubs |
Spoke is deployed and live. AdapterSpokeV1, the Spoke beacon and the three per-asset Spoke Sources are deployed on BNB Chain, and the bStock index spoke pool has been funded since VIP-670. Onboarding a further market is a governance action, in this order:
setAllowedSupplier(vToken, <SpokeSource>, true)on the spoke pool.addResource(vToken, AdapterSpokeV1)on the Spoke Source. The adapter rejects a registration the market would not accept, and also rejects a market its own Comptroller does not list.setInnerDepositQueueandsetInnerWithdrawQueueon the Spoke Source, so the new market is routed to.- On the Hub, place the Spoke Source in the outer deposit queue if it is not there yet.
On BNB Chain the Spoke Source of every Hub is second in the outer deposit queue, [Core, Spoke, Flux], and last in the outer withdraw queue. See How deposits and withdrawals are routed for the full order per Hub.
FRV carries no resource at launch. An FRV Source is deployed and registered on every Hub with its caps set, but no Fixed-Rate Vault instance exists for USDT / USDC / U on BNB Chain yet, so the onboarding proposal calls addResource on the Core and Flux Sources only. FRV is therefore kept out of the outer deposit queue entirely and, at launch, placed last in the outer withdraw queue — not because it can serve withdrawals, but because setOuterWithdrawQueue rejects a queue that omits a registered Source with non-zero totalAssets(), and that total counts idle balance: omitting FRV would let a 1-wei donation permanently block the Operator from reordering the queue. That follow-up was VIP-657: it registered the Solv (Ceffu custody) vault on the USDT Hub’s FRV Source and the Asseto CASH+ vault on the U Hub’s FRV Source, and raised their FRV percentage caps from 30% to 50% of TVL (VIP-664 later raised the U Hub’s to 90%); the USDC Hub’s FRV Source remains unwired. VIP-667 then added a second vault, Hash Global hBNB, to the U Hub’s FRV Source. FRV is still absent from the outer deposit queue, so it is filled only by the Operator’s reallocate.
Centrifuge was added later, on the USDT and USDC Hubs. VIP-661 onboarded the Centrifuge family, deployed beforehand by deploy script, and brought up the USDT Source; VIP-666 added the USDC one and refreshed both published APYs. Each registered the JTRSY and JAAA vaults for its own asset behind AdapterCentrifuge, armed a NAV band on each, published an APY, and added the Source with a 5,000,000 absolute cap and a 25% percentage cap. Like FRV, Centrifuge is out of the outer deposit queue and sits right after FRV in the outer withdraw queue, so it is filled only by reallocate. The U Hub has no Centrifuge Source. See Centrifuge lifecycle.
Contracts
Section titled “Contracts”- Hub — the ERC-4626 entry point: routing flows, dual caps, per-tx withdrawal cap, fees, multi-level pause, Operator reallocation, and the full Solidity API.
- Yield Groups:
YieldGroup(the generic router, deployed three times: as the Core, Flux and Spoke families),YieldGroupFRVandYieldGroupCentrifuge: theIYieldGroupBaseimplementations, per-resource registry / queues / caps, the FRV lifecycle, and the Centrifuge lifecycle and NAV band. - Adapters:
AdapterCoreV1,AdapterFlux,AdapterFRV,AdapterSpokeV1,AdapterCentrifuge: the stateless, delegatecall-dispatched protocol translators. - Interfaces —
IYieldGroupBase(with its family extensionsIYieldGroup,IYieldGroupFRVandIYieldGroupCentrifuge) andIResourceAdapter, the boundary contracts, plus whereINavGuardandIHubLensare documented. Migrator— a stateless, permissionless, non-upgradeable helper for one-click migration of a Venus Core position into a Hub (migrateFromCore/migrateFromCoreBNB).HubLens— a stateless, unowned, non-upgradeable read-only helper. The Hub does not compute a deposit ceiling, soHubLensis where a frontend or an integrator reads one:maxDeposit(hub),maxMint(hub),depositCapacityBreakdown(hub)and the blendedspotAPYBps(hub). Every function takes the Hub as a parameter, so one deployment serves every Hub — see Sizing a deposit.
HubRegistry — one per chain, the canonical directory of deployed Hubs. Governance calls addHub(address) / removeHub(address) (both ACM-gated); everyone else reads hubForAsset(address), assetForHub(address), isHub(address), getHubs() and getHubsCount(). It emits HubAdded / HubRemoved, and an indexer should seed from state on HubAdded rather than relying on log ordering. Each asset may have at most one Hub (AssetAlreadyHasHub).
Key features
Section titled “Key features”- Atomic-or-revert deposits, withdrawals, and reallocations — no partial fills.
- Dual caps per Source (absolute amount and percentage of Hub TVL; the stricter binds) plus an optional per-resource cap and a per-transaction withdrawal cap.
- Multi-level pause — Hub, Source, or single resource, each independent.
- Reentrancy-guarded value paths — every entry point that moves assets is
nonReentrant:deposit/mint/withdraw/redeem/reallocate/emergencyReallocate/accrueFees/sweepon the Hub, anddeposit/withdraw/depositResource/withdrawResource/sweepon each YieldGroup. The ACM-gated admin setters are not individually guarded; they rely on ACM gating instead. - Asymmetric permissions — governance holds every gated function except
reallocate. The Operator can pause and raise or lower Source and resource caps; the Guardian can also pause and replace a resource adapter. Both can unpause individual resources. Unpausing a Hub or YieldGroup, registering a route, raising the withdrawal cap and setting fees remain governance-only. Every permission is granted throughAccessControlManagerV8; see Permissions. - Stateless shared adapters — zero storage, delegatecall dispatch; a new protocol family needs only a new adapter, not a Hub change.
- Fees off at launch — management and performance fee machinery exists but ships at
0/0.
Deployment
Section titled “Deployment”The Hub uses a beacon-proxy model: one UpgradeableBeacon per family per chain (Hub, Core, FRV, Flux, Spoke, Centrifuge), each owned by governance — upgrading a beacon upgrades every vault of that family atomically; per-asset instances are beacon proxies. Deploy scripts only deploy and initialize the proxies; ACM wiring, addYieldGroup / addResource, and queue configuration are separate governance (ACM-gated) actions.
HubRegistry is the exception: it is a chain-level singleton behind a TransparentUpgradeableProxy, not a beacon proxy, so it is upgraded independently of every Hub. On BNB Chain mainnet that proxy is administered by Venus’s shared DefaultProxyAdmin, the same one that administers the core pool and isolated pools; the BSC testnet deployment predates that decision and still carries a registry-specific ProxyAdmin.
v1 targets BNB Chain, launching with three assets: USDT, USDC and U.
The contracts are deployed on BNB Chain mainnet. Deployment only creates and initializes the proxies — the governance proposal that onboards them grants the ACM roles, registers each Hub with the HubRegistry, wires the resources and queues, and seeds each Hub with a bootstrap deposit. Until that proposal executes, the Hubs are deployed but unwired.
BNB Chain mainnet (chain ID 56)
Section titled “BNB Chain mainnet (chain ID 56)”| Asset | Hub |
|---|---|
| USDT | 0x18AfDACF30F8671021dec4b78297E39d2FE87226 |
| USDC | 0x9D2D9592cF8DFbf59107fAab703d08494BE14617 |
| U | 0x0e5AA174d4F31b757a237eb1999DE151596788B0 |
HubRegistry is deployed at 0x6D93Fd479f2d37445CFBe132412e316a0364acc2. Prefer resolving Hub addresses through it rather than hard-coding them. The Deployed Contracts page carries the same addresses as explorer links, including the per-asset YieldGroup proxies.
Supporting contracts:
| Contract | Address | Notes |
|---|---|---|
HubLens | 0xE5d8A002A794CcDba248ba774a359eF2B9E4Ba8B | Stateless, unowned, non-upgradeable. Deposit sizing and blended APY for every Hub, see Sizing a deposit |
Migrator | 0xfe6b8BEf1215C19Cd247FbF495ef560932F1Eb9B | Stateless, permissionless, non-upgradeable. One-click migration of a Venus Core position into a Hub via migrateFromCore / migrateFromCoreBNB (plus *WithConsent variants) |
HubBeacon | 0x0f20e1004962e2DF16c16FC15460Dc6480626321 | Upgrades every Hub atomically |
CoreBeacon | 0x195a0F1BCF73C3Beb609a1271E8E08b8E4c098C6 | Core-family YieldGroups |
FluxBeacon | 0x9bb6a3Ac5955fA8dc236560CA9D51483d1d79f15 | Flux-family YieldGroups |
FRVBeacon | 0x8A5EceDD726246682402430b9B24c19bF61B7f1d | FRV-family YieldGroups |
SpokeBeacon | 0x652AAa1CD21f47a92D04680C1d9Bf99cC1Fb8975 | Spoke-family YieldGroups |
CentrifugeBeacon | 0xAe90Cfb3E2Bc97508F58E7e076Acf38f3bfC820f | Centrifuge-family YieldGroups |
AdapterCoreV1 | 0xa061cC2F62BDa2D6bA53Fb98847aD9822DA085dd | Shared singleton; replaced its predecessor in VIP-669 |
AdapterFlux | 0x9a1a7F6aebA4a1A3e85Ae1Dba90a7A2A52803404 | Shared singleton; replaced its predecessor in VIP-669 |
AdapterFRV | 0x1824caA965Ac05ae5C9C2819e045337e2cF5657c | Shared singleton; replaced its predecessor in VIP-669 |
AdapterSpokeV1 | 0x231915FfE3e3A6Be09B0E5c73EFA2F1a4FF8Aa69 | Shared singleton |
AdapterCentrifuge | 0xaa9D52758890997D91950E595886FF9CDEca81ae | Shared singleton; replaced its predecessor in VIP-669 |
DefaultProxyAdmin | 0x6beb6D2695B67FEb73ad4f172E8E2975497187e4 | Venus’s shared ProxyAdmin, administering the registry’s TransparentUpgradeableProxy; governance-owned |
Each asset also has one YieldGroup proxy per family it is wired to (CoreSource_*, FluxSource_*, FRVSource_*, SpokeSource_*, CentrifugeSource_*), and the set differs per Hub; resolve them from the Hub’s registeredYieldGroups() rather than hard-coding.
Hub parameters. Live values; all three assets are 18-decimal. Only the FRV and Spoke caps differ per Hub, the FRV row includes VIP-657 and VIP-664, and only the USDT and USDC Hubs have a Centrifuge Source:
| Parameter | USDT | USDC | U |
|---|---|---|---|
| Share token name / symbol | Venus Hub USDT / vhUSDT | Venus Hub USDC / vhUSDC | Venus Hub U / vhU |
decimalsOffset | 6 | 6 | 6 |
maxWithdrawalSize (per tx) | 10,000,000 | 10,000,000 | 10,000,000 |
| Core cap (absolute / %) | 2,000,000,000 / disabled | same | same |
| Flux cap (absolute / %) | 7,000,000 / 20% | same | same |
| FRV cap (absolute / %) | 5,000,000 / 50% | 5,000,000 / 30% | 5,000,000 / 90% |
| Spoke cap (absolute / %) | 300,000,000 / 50% | 90,000,000 / 50% | 30,000,000 / 50% |
| Centrifuge cap (absolute / %) | 5,000,000 / 25% | 5,000,000 / 25% | no Centrifuge Source |
| Management / performance / redeem fee | 0 / 0 / 0 | 0 / 0 / 0 | 0 / 0 / 0 |
A Spoke Source can hold at most the lower of two limits: the Hub’s effective cap for it, which is the stricter of the absolute and the percentage cap and is read with yieldGroupEffectiveCap(source) on the Hub, and the liquidity market’s supply cap in the spoke pool, 5,000,000 (supplyCaps on the SpokeComptroller). On 2026-10-29 the 50%-of-TVL cap is the one that binds on the USDT Hub (about 2.64M of a 5.27M TVL) and the USDC Hub (about 0.64M of 1.27M). On the U Hub the effective cap is about 5.5M, so the 5,000,000 market supply cap binds instead. These are today’s figures. For a deposit the percentage cap is priced against TVL including that deposit, so a deposit can place more than yieldGroupEffectiveCap shows; size deposits with HubLens rather than off the effective cap. Both limits move with TVL and governance, so read them live. See spoke pools.
feeRecipient is 0xF322942f644A996A617BD29c16bd7d231d9F35E9 on all three. Core’s percentage dimension uses the 10_000 BPS sentinel, so only its absolute cap binds; Flux is held to 20% of TVL, which at launch sits well under its absolute cap, so it fills through Operator reallocate rather than from the deposit queue. Each Hub is seeded with a 10-token bootstrap deposit from the Treasury whose shares are minted to the burn address, so totalSupply is never zero and the refill-from-empty branch cannot be re-opened.
Role holders. Granted by the onboarding proposal, not baked into the bytecode — see Permissions:
| Role | Address |
|---|---|
| Governance | 0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396 — the Normal Timelock |
| Operator | 0x83f426233B358A36953F6951161E76FB7c866a7A — the routine keeper multisig |
| Guardian | 0x1C2CAc6ec528c20800B2fe734820D87b581eAA6B — no-delay containment multisig |
| Keeper | 0x194b1F6c57d023Fa59497ee5A7976dB47f183929 — Centrifuge Sources only: claimDeposit, claimRedeem, claimCancelDeposit, claimCancelRedeem (VIP-661, VIP-666) |
BSC testnet (chain ID 97)
Section titled “BSC testnet (chain ID 97)”A parallel deployment exists for integration testing. The USDT Hub below is the reference deployment, but the testnet registry now lists seventeen Hubs over mock assets (USDT, WBNB, USDC, FDUSD, BTCB, ADA, AAVE, CAKE, ETH, DOGE, LTC, SOL, SXP, BUSD, TUSD and TRX, plus one Hub over the vhTUSD share token), stood up for QA scenarios with per-Hub wiring that does not follow the mainnet shape. The full list is on the Deployed Contracts page. Either way the mainnet asset trio does not map onto testnet, so a harness written against the mainnet asset list will not carry over.
| Contract | Address |
|---|---|
Hub_USDT | 0x7cE6ADF754D0eC81A6CF8ACd9C7454F45077dc61 |
HubRegistry | 0x5346f648029d1D1d1034e09e8AD7a115f5D7A159 |
Migrator | 0x343D518d8C89f9B5D770000F1ed80f45bF1419f5 |
HubLens | 0x0D0C640AA4da71cE610EFD6a04acCE6e3Ae419C2 |
CoreSource_USDT | 0x11e39DC7b8b16BBDA8D9C2903dF741Ae9341Ec88 |
FluxSource_USDT | 0x044E572144bc08ed2D90E081EeEd7b5b6Cb01016 |
FRVSource_USDT | 0xA0Fb0fFeBdcB7F45A3Ec841cCE7F78B7CeBD0f82 |
SpokeSource_USDT | 0xb9Bf8232474aF0A18BbA0CbCc3bA10efD51542e2 |
CentrifugeSource_USDT | 0x8DFF12277C44E73cbF551ceB6E5Ae1eD4CC85542 |
AdapterCoreV1 | 0x07c80ed1F928913ab68E1fABB2fe0439CdC99F88 |
AdapterFlux | 0x51d8cAdc16Df3F8Cd0D1B536e943FbDcE77AC523 |
AdapterFRV | 0xcdd9cf27C388dAc9e89De257505aff9290183537 |
AdapterSpokeV1 | 0x439034668f201B9f2D45286b4518e6DB122B5e17 |
AdapterCentrifuge | 0x63Ce07c3F1500B283B6d3451BdC3E3C6211a6c7F |
SpokeBeacon | 0x58099BEaa6A00F493eF67fF953866DDA4a502389 |
HubRegistryProxyAdmin | 0x9f8413eEE33D434F6D4f40C83181f32A831c9ef7 |
Testnet is not a faithful mirror of mainnet. Four differences will break assumptions carried over from a testnet harness:
- The share token is named
Vault Share/vSHARE, a placeholder — not theVenus Hub <asset>/vh<asset>pair mainnet uses. - FRV is fully wired on testnet: eight Fixed-Rate Vaults are registered as resources on the USDT Hub’s FRV Source, and the FRV Source sits in both outer queues. On mainnet only the USDC Hub’s FRV Source has no resource. Testnet Centrifuge carries one mock vault rather than the two real funds, and like mainnet it sits in the withdraw queue only.
- On the USDT Hub, Core, FRV, Spoke and Centrifuge are effectively uncapped (
type(uint128).maxabsolute, percentage dimension disabled) and Flux is capped at about 750 USDT, rather than the tiered mainnet values. The per-transaction withdrawal cap is also lower. - The registry proxy is administered by a registry-specific
HubRegistryProxyAdmin, not the sharedDefaultProxyAdminmainnet uses.
Audits
Section titled “Audits”The Liquidity Hub was audited by HashDit (2026/07/07) and Cantina (2026/08/11), the Centrifuge yield group by HashDit (2026/09/04), and HubLens and the capacity math behind it by HashDit (2026/09/24). The reports are in the venus-liquidity-hub repository, except the HubLens report, which is pinned at commit 01fac4a of branch fix/hub-maxDeposit until PR #20 merges. All are indexed, with their scope, on the Security & Audits page.