A yield-bearing ERC-4626 + ERC-7540 + ERC-7887 vault for HyperEVM (Hyperliquid,
chain id 999). Captures funding-rate yield via a keeper-assisted delta-neutral
position (spot long + perp short) held in the vault's own Core account.
Share token: hvUSDC. Underlying: native bridged USDC.
┌─────────────────────────────────┐
user deposits │ UsdcVault │ hvUSDC (shares)
USDC ─────────▶ │ (ERC-4626 + 7540 + 7887) │ ─────────▶
│ UUPS-upgradable, 48h timelock │
└───────────────┬─────────────────┘
│ CDW.deposit()
▼
┌─────────────────────────────────┐
│ Vault's HyperCore account │
│ • Spot USDC buffer │
│ • Long spot (HYPE/UETH/UBTC) │
│ • Short perp (delta-neutral) │
└─────────────────────────────────┘
│
│ keeper EOA (agent wallet) signs
│ spot + perp orders via L1 API
▼
Hyperliquid L1
- Deposit bridges USDC EVM → Core via
CoreDepositWallet.deposit. Shares are minted on arrival (inflight-buffer covers the gap so NAV stays conservative). - Redeem is 2-phase (ERC-7540):
requestRedeem→ keepermarkRedeemReady→ userredeem(shares, receiver, controller). The keeper pre-funds the EVM side viawithdrawFromHyperCoreToEVMbefore the request is marked ready. - Cancel (ERC-7887) allows users to pull shares back before
markReadyviacancelRedeemRequest→claimCancelRedeemRequest. - NAV is read live from HyperCore precompiles inside
totalAssets()— no trusted oracle, no mirror storage.
| Module | File | Purpose |
|---|---|---|
UsdcVault |
src/vault/UsdcVault.sol |
Main proxy — ERC20/4626/7540/7887 surface |
VaultStorage |
src/vault/VaultStorage.sol |
UUPS storage layout |
VaultLens |
src/vault/VaultLens.sol |
Read-only dashboard helpers |
NavLib |
src/vault/NavLib.sol |
HyperCore NAV precompile reads + admin helpers |
RedeemLogic |
src/vault/RedeemLogic.sol |
Async redeem FIFO aggregation + cancel logic |
RedeemQueueLib |
src/vault/RedeemQueueLib.sol |
Redeem-request queue primitives |
DepositLogic |
src/vault/DepositLogic.sol |
Deposit + auto-bridge logic |
HyperCoreBridgeLib |
src/vault/HyperCoreBridgeLib.sol |
Core→EVM bridging (Action 13) |
CoreWriterLib |
src/hypercore/CoreWriterLib.sol |
CoreWriter action encoding |
Logic/Lib modules are external libraries (delegatecall) so UsdcVault stays
under the EIP-170 24,576-byte cap while keeping the user surface in one proxy.
totalAssets() = _evmBalance() + _coreNAV() + _inflightBuffer() − accruedFees— live read, no mirror; fees excluded to keep share price honest- Share conversion uses virtual-offset anti-inflation (
VIRTUAL_ASSETS/SHARES = 1e6) - Performance fee snapshot is frozen at
markRedeemReady— admin cannot retroactively raise the rate on ready requests reservedEvmBalance == Σ _reservedAssetsPerRequest[rid]— keeper bridge operations cannot consume funds already reserved for a ready redeemuserDeposits[u] + lockedPrincipal[u]counts towardmaxUserDeposit— cap cannot be bypassed by partially-active redeem requests- ERC-20 share transfers proportionally migrate
userDepositsso recipients do not pay the performance fee on what is actually a zero-P&L position - Withdraw (by assets) is disabled; all exits happen via
redeem(shares, receiver, controller) - Operator-initiated
redeemandclaimCancelRedeemRequestMUST setreceiver = controller, preventing operator redirection of user funds emergencyRedeemis admin-gated, refuses to act on a user-initiated cancel, and is capped atprincipalSnapshotso admin path never over-pays vs cost basis- Upgrades pass through a 48h timelock with Guardian veto
(
guardianCancelUpgrade); admin can freeze upgrades permanently by revokingADMIN_ROLEafter reaching stability - Negative perp NAV is subtracted from
_coreNAV(floored at 0, int64.min safe via int256 promotion) - Deposits gated on oracle↔mark perp divergence and primary/tracked-spot
spotPx↔ perporaclePxdivergence, both bounded at 5%
Dependencies are tracked as git submodules — pulling them is a single command regardless of how you clone:
# if you cloned without --recurse-submodules:
git submodule update --init --recursive
# or in one step when cloning:
git clone --recurse-submodules https://github.com/hypurrquant/hyperliquid-vault.gitAlternatively, forge install (no arguments) restores the submodules pinned in
foundry.lock / .gitmodules.
Then:
forge build
forge testSolidity 0.8.28, via_ir = true, optimizer_runs = 1, evm_version = cancun.
Apache License 2.0 — see LICENSE.