Aave v3 Risk Framework
Smart contract security audit by TierZero · 2023-09-15
Independent research. This is an unsolicited security analysis published by TierZero — not a commissioned audit, and no certificate is issued. It reflects our own review of public code and on-chain events.
Findings summary
Independent research — not a commissioned audit. This is an educational design review of a public, battle-tested protocol, not a certification of current live code.
What it is
Aave v3, live on Ethereum since January 2022, replaced v2's flat per-asset risk model with a set of composable controls: isolation mode, efficiency mode (e-mode), siloed borrowing, and hard supply/borrow caps. The problem they solve is structural, not cosmetic. In a shared-liquidity pool, listing any new asset as collateral extends borrowing power against every other asset in the pool. v2 had no way to say "let this asset in, but keep its blast radius small." v3 does, and that's what let Aave governance list long-tail and newly-bridged assets faster without re-running the whole pool's risk model every time.
Threat model
The scenarios this framework is built against:
- An oracle for a thin-liquidity asset gets manipulated (flash loan, low-depth AMM, stale feed), and the attacker uses the inflated collateral value to drain deep, liquid assets like USDC or WETH from the pool.
- A newly listed, unproven asset craters in price and the resulting bad debt is socialized across suppliers of unrelated assets, because collateral value was fungible across the whole pool.
- Two nominally "correlated" assets (stETH/ETH, USDC/USDT) are treated as fully correlated for LTV purposes, but a depeg event proves the correlation assumption wrong at the worst possible time.
- Demand for a single asset grows faster than its real-world liquidity or oracle robustness can support, and the pool ends up with concentration risk nobody sized for.
None of these are novel — they're the standard failure modes of any shared lending pool. What's worth reviewing is how deliberately Aave's mitigations are scoped to each one individually rather than relying on a single global parameter.
Why the design holds (key invariants & mitigations)
Isolation mode caps the aggregate dollar value of debt that a given collateral asset can unlock, independent of how many units of that asset are supplied. The ceiling is a fixed number set by governance, not derived from the asset's own oracle price — so a price manipulation on the isolated asset can push a position toward liquidation, but it cannot raise the ceiling itself. A borrower in isolation mode is also restricted to a single isolated collateral and can only borrow assets explicitly flagged borrowableInIsolation.
function validateBorrow(asset, amount, user) {
if (isolationModeActive(user)) {
isolated = getIsolatedCollateral(user);
require(asset.borrowableInIsolation, "ASSET_NOT_BORROWABLE_IN_ISOLATION");
newDebt = isolated.totalIsolationDebt + normalize(amount);
require(newDebt <= isolated.debtCeiling, "DEBT_CEILING_EXCEEDED");
}
if (eModeCategory(user) != 0) {
require(eModeCategory(asset) == eModeCategory(user), "INCONSISTENT_EMODE_CATEGORY");
}
require(totalDebt(asset) + amount <= asset.borrowCap, "BORROW_CAP_EXCEEDED");
}
E-mode grants higher LTV and liquidation thresholds only when collateral and debt both belong to the same declared category. The efficiency gain is real (near-1:1 LTV for stablecoin or LST pairs), but it's gated at every borrow and every collateral toggle — a user can't mix a high-LTV correlated position with an uncorrelated borrow to smuggle extra leverage past the risk engine.
Supply and borrow caps are hard ceilings enforced in the validation path on every supply and borrow transaction. They don't stop an individual asset from being volatile; they stop volatility in one asset from translating into unbounded exposure for the whole pool. The invariant that matters here: maximum value-at-risk from any single asset is a known, governance-set number, not an emergent property of market demand.
Layered together, these are defense-in-depth in the literal sense — isolation mode bounds collateral-side contagion, siloed borrowing bounds debt-side contagion, e-mode bounds correlation-assumption risk, and caps bound raw exposure size. No single control is doing all the work, which is why a failure in one (a mispriced e-mode category, say) doesn't automatically compromise the others.
Where implementers get it wrong
Forks and integrators reuse Aave v3's code but don't reuse its risk discipline:
- Caps get left at zero or effectively unlimited for newly listed assets because nobody wired up the governance process to set them — the mechanism exists in code but is inert without an actively maintained parameter.
- Debt ceilings are denominated in fixed-decimal USD units; periphery contracts (leverage vaults, one-click aggregators) that batch or wrap isolated positions sometimes misread those decimals, silently over- or under-restricting borrowers.
- E-mode categories are set once and forgotten. An asset added to a "correlated" category can decorrelate later (a liquid-staking derivative or algorithmic stablecoin losing its peg), and the elevated LTV becomes the liability nobody re-reviewed.
- Isolation mode and siloed borrowing get treated as interchangeable when they restrict opposite sides of the position — assuming one substitutes for the other leaves a real gap for genuinely risky assets.
This is exactly the kind of gap that shows up in periphery and integration code rather than the core protocol, which is why we treat parameter wiring and cap configuration as first-class checklist items in smart contract audits — the core logic can be sound and the deployment still unsafe. It's also a recurring theme in composability failures generally; we cover an analogous pattern in EVM approval flows in our review of Permit2 gasless approvals and EVM sniping bot risk, and the cross-chain equivalent in cross-program invocation risk in Solana DeFi.
Takeaways
- Isolation mode, e-mode, and caps are bounding mechanisms, not vulnerability fixes — they assume individual assets will misbehave and limit the damage.
- The code enforcing these controls is only as safe as the governance parameters feeding it; an audit of a fork needs to check both.
- Category and ceiling assumptions decay over time as market correlations shift — this needs a maintenance process, not a one-time review.
- Isolation mode and siloed borrowing are not redundant; they cover different attack directions and both matter for risky listings.
If you're forking or integrating this pattern, a thorough code review before mainnet deployment is where these configuration gaps actually get caught — reach out to TierZero's smart contract audit team before you list your first asset.
Need your contracts audited?
Manual review + tooling across TON, Solana and EVM — certificate and full report included.
Get an audit