How Aave Stable Vaults work

Aave Labs open-sourced the Stable Vaults contracts at aave-dao/stable-vault after the July launch. I spent the last week reading the codebase and the architecture docs and wrote up how the system fits together, since there isn’t a single community-level explainer yet.

Corrections welcome a few things below are inferences from the code, and I’ve marked them.

Source: GitHub - aave-dao/stable-vault: Stable, per-user earning rate vault protocol developed by Aave Labs · GitHub and Stable Vault Architecture | Aave Protocol Documentation

1. The problem it solves

Aave market rates are variable. Stable Vaults promise depositors a fixed per-second rate, then earn that yield behind the scenes across Aave markets and other ERC-4626 strategies, on more than one chain. Three design goals show up everywhere in the code:

  1. Principal is always redeemable; interest is only paid out of realized surplus.
  2. Accounting is separated from earning, across chains.
  3. Users never touch a bridge directly.

2. Two kinds of chains

Accounting Chain (Arbitrum for the Aave App deployment). This is the source of truth. It hosts:

  • StableVault - user entry point: deposits, SubVault assignment, the two-step withdrawal.
  • FundsHandler - aggregates the system’s total asset value across local balances and remote chains.
  • Allocator - holds idle funds and moves them into whitelisted ERC-4626 strategies.
  • AccountingChainGateway - sends funds out and validates messages coming back.
  • IouTokenManager, AssetRegistry, PriceOracle, policies.

Earning Chains (one deployment per chain). Each hosts an EarningChainGateway, its own Allocator, and an EarningChainStateProvider that publishes a balance snapshot. Earning chains can only send funds back to their accounting chain, never sideways.

Bridging uses adapters; the repo ships Chainlink CCIP and a.DI adapters.

3. SubVaults and rates

A SubVault is a virtual bucket inside StableVault with its own perSecondRate. Users hold shares in exactly one SubVault; the rate a user earns is whichever SubVault they were assigned to at deposit (via policyData). This is how per-user or per-tier rates work without deploying separate vaults and loyalty tiers, promo rates, and partner-specific rates are just different SubVaults.

4. Deposit flow

deposit(user, asset, amount, policyData) on StableVault:

  1. Asset must be registered in AssetRegistry.
  2. Price is validated through PriceOracle.validatePrice (staleness and min-price checks; prices above 1 RAY are capped to 1 RAY).
  3. Amount is converted to SubVault shares at the current conversion rate; the position is credited.
  4. Funds land idle on the local Allocator. Nothing is deployed to a strategy at deposit time an off-chain manager later calls rebalance().

5. Withdrawal flow (two steps, IOU-based)

Step 1 - requestWithdrawal(user, amountInRay, policyData) on the accounting chain. Shares are burned and the user receives IOU tokens denominated in the common unit (USD). The principal portion of a position is always claimable as IOUs; the interest portion is gated by the system’s trusted surplus.

Step 2 - executeWithdrawal(...) on the accounting chain, or exchangeIouTokens(...) on an earning chain. IOUs are burned, the WithdrawalExecutionPolicy applies fees/operational costs, assets are pulled from the local Allocator, and the user receives their chosen output asset.

IOUs can be bridged between chains via IouTokenManager.bridgeTokens. The stated reason is liveness: users can exit on an earning chain even if managers are offline and haven’t repatriated funds. Note the bridge fee is paid by the caller and pulled by the specific bridge adapter, the README explicitly warns to approve only the quoted fee, not unlimited allowance.

6. Multi-asset and the 1:1 swap rule

The vault accepts several stablecoins interchangeably (deposit USDC, withdraw USDT). Swaps inside the Allocator go through a Swapper and are enforced at a nominal 1:1 rate. Any slippage or venue fee is covered by an external Slippage Coverage Vault, not by depositors.

7. Surplus and the cross-chain oracle

This is the part I found most interesting. FundsHandler computes total system value by summing local balances plus each registered earning chain’s balance, read on demand from ChainBalanceOracle. Earning-chain balances come from EarningChainStateProvider.getState() snapshots published through a Chainlink bundle feed and decoded by ChainlinkChainBalanceOracleAdapter.

If a snapshot is stale (heartbeat + buffer exceeded), that chain contributes zero to the total. So a lagging oracle makes the system under-estimate surplus, which delays interest withdrawals rather than overpaying them. Inbound RETURN_FUNDS / BURN_IOU_TOKEN messages are also validated against the source-chain block number in the latest snapshot.

8. Manager roles (the off-chain half)

Managers can:

  • pushFundsToChain (accounting → earning) and pushFundsToAccountingChain (back).
  • Add / remove / trust / distrust / order strategies on each Allocator.
  • Call rebalance() to move funds between strategies or swap assets.

Inference: the repo contains contracts plus deploy scripts only. The service that decides when to rebalance and how much to send to each chain and strategy — effectively an allocation solver under constraints (promised SubVault rates, pending IOU liquidity, bridge cost, strategy trust ordering) — is not in the public repo. If anyone from Aave Labs can say whether that layer is planned to be opened, I’d be interested.

9. Security

The audits/ folder has ten reports from Certora, ChainSecurity and J. Feist dated Jan–Jul 2026, including a separate Certora review of the a.DI adapter. License is proprietary (All Rights Reserved under Aave Labs), so this is source-available rather than open-source. Bug bounty details are listed as “coming soon”.

10. Diagram

Open questions

  1. Which chains are live as earning chains today, and what’s the current strategy list per Allocator?
  2. How is the SubVault rate chosen relative to realized strategy yield — is there a target coverage ratio (surplus / promised interest) that triggers rate changes?
  3. Is the manager/rebalancer expected to be permissioned indefinitely, or is there a path to a Risk Steward-style bounded automation like the DAO uses for v3 parameters?
  4. Any plans to publish a subgraph or indexer schema for StableVault / IouTokenManager events? I’m building an open one and would rather align with something official.

Happy to be corrected on any of the above and I’ve tried to stick to what’s in the code.

Kumar Shivam - Github & X