Architecture
Vault metadata
The full machine-readable metadata for the Hubra Earn USDC vault:USDC has 6 decimals on-chain (
1.50 USDC = 1_500_000 base units). raUSDC has 9 decimals. When reading raUSDC balances directly from the chain, scale by 10^9, not 10^6. The Hubra app and API surface USDC-denominated values to hide this asymmetry.Deposit flow (technical)
What happens
- Hubra’s API calls
POST https://api.voltr.xyz/vault/3maCu...6gNQ/deposit. - Voltr returns an unsigned base64 transaction. Hubra normalizes it to standard base64 and forwards.
- The transaction includes:
- SPL Token transfer instruction: USDC from your associated token account to the vault.
- Voltr vault deposit instruction: mints raUSDC at the current share price.
- (If needed) Associated token account creation for raUSDC.
- Your wallet signs.
- The transaction is broadcast. On confirmation, USDC is in the vault, raUSDC is in your wallet.
Request shape (Voltr API, called server-side)
lamportAmount is the USDC amount in base units. With USDC decimals = 6, 1.50 USDC = 1_500_000 base units. Hubra’s API takes a decimal string from the caller and converts to base units server-side.
Share-price math
raUSDC is minted at the current share price:/vault/{vault}/share-price endpoint, surfaced through Hubra’s GET /api/v1/strategies/usdc-earn.
Programmatic deposit
POST /api/v1/broadcast with route: "rpc". There is no Sanctum involvement; plain RPC handles the broadcast.
Withdraw flow (technical)
USDC Earn supports direct withdraw only. Other Voltr vaults can have queued withdraws with awithdrawalWaitingPeriod; this one does not.
Direct withdraw
POST https://api.voltr.xyz/vault/3maCu...6gNQ/direct-withdraw returns an unsigned transaction that:
- Burns your raUSDC.
- Transfers USDC from the vault to your associated USDC token account.
- Settles in a single transaction. No cooldown.
isWithdrawAll semantics
Two withdraw modes:
Use
isWithdrawAll: true when you want to drain the position fully without computing the exact raUSDC count. The vault handles the math.
Programmatic withdraw
route: "voltr". Broadcast via route: "rpc".
Whitelisted adapters
The Voltr vault program is configured with a whitelist of adapters: the only contracts the vault is allowed to deposit USDC into. Each adapter is independently audited. The current adapter set includes lending markets on:- Kamino — automated lending
- Jupiter — lend infrastructure
integrations array in the response shows each adaptorPk (the adapter program account) and its whitelisted flag.
The autonomous rebalancer decides where USDC moves between adapters based on relative yield. The rebalancer source code is public:
vaults-rebalancer
Read the allocation logic on GitHub.
Fee structure
Voltr’s vault fee config has four slots; for the Hubra Earn vault, each is set as follows:
The displayed APY is the venue-blended yield net of any underlying market spreads (e.g., Kamino’s reserve fee on its lending markets). Those are not Hubra fees; they are baked into the upstream’s quoted APY.
Verify the fee config on-chain via
fetchUsdcVaultStats() (/vault/{vault}/feeConfiguration).
raUSDC: safe to move, never burn
raUSDC is a standard SPL token, so you can hold, transfer, or trade it, and the claim on your vault position moves with it. It is not yet integrated into external DeFi protocols. Withdraws happen by redeeming raUSDC inside the vault, which converts it back to USDC at the current rate. If you connect an external wallet (Phantom, Backpack, Solflare) and deposit into Earn, raUSDC appears in that wallet. To redeem it for USDC, use the Hubra app. For the full token reference, see raUSDC.Reading vault state
Three useful Voltr endpoints (called server-side by Hubra; surfaced through the agent API):
The vault snapshot returns the full state:
totalValue, apy.{oneDay,sevenDays,thirtyDays,allTime}, dailyStats.apyData[], allocations[], integrations[], feeConfiguration. Hubra surfaces the headline numbers; the full snapshot is one HTTP call away if you need the rest.
Risks
USDC Earn is distinct from validator staking risk. You are exposed to:- Vault smart-contract risk. Voltr’s vault program. Audited by FYEO and secured by Sec3’s X-RAY static analysis tool, but no contract is risk-free.
- Adapter risk. Each whitelisted adapter is its own contract surface.
- Underlying venue risk. Kamino, Jupiter, etc. — each has its own audit and operational history.
- Stablecoin risk. USDC is a Circle-issued stablecoin and carries the issuer risk associated with that.
Common questions
Why is the response transaction sometimes large?
Why is the response transaction sometimes large?
The transaction may include an associated token account (ATA) creation for raUSDC if your wallet has not held it before. ATA creation costs ~0.002 SOL of rent (covered by Hubra in the app, paid by the wallet for direct API callers).
Can I deposit USDT, USDS, or other stablecoins?
Can I deposit USDT, USDS, or other stablecoins?
The current vault is USDC-only. Deposits in other tokens would need to be swapped to USDC first.
What is the difference between `direct-withdraw` and a queued withdraw?
What is the difference between `direct-withdraw` and a queued withdraw?
Voltr’s vault program supports both. The Hubra Earn vault is configured for direct (instant) withdraws —
withdrawalWaitingPeriod is 0. A queued withdraw would require waiting withdrawalWaitingPeriod seconds before the funds settle. Not used here.How does yield show up?
How does yield show up?
The raUSDC redemption rate climbs continuously as the underlying allocations earn yield. Your raUSDC balance stays fixed; each unit becomes worth more USDC over time.
Is my principal guaranteed?
Is my principal guaranteed?
No. Like any DeFi yield product, USDC Earn’s principal carries smart-contract, protocol, and stablecoin risk.
Where can I see exactly where my USDC is right now?
Where can I see exactly where my USDC is right now?
Call Voltr’s vault snapshot endpoint and read the
allocations[] array. Each entry shows the org name, strategy description, and positionValue of vault-deployed USDC at that venue.Get started
Deposit USDC
Open the app and choose Earn.
POST /api/v1/stake
Build a deposit transaction programmatically.