Three Aave Versions, One Unified Data Model

Aave V2, V3 and V4 have different onchain structures, field layouts, rate models and architectures. Here's how we map all three into one unified data model so they can be queried identically.


Illustration for “Three Aave Versions, One Unified Data Model”

A previous article made the general case: onchain lending is fragmented, and the 1delta API maps more than 500 disjoint markets into a single queryable surface. This piece examines the hardest version of that problem within a single protocol family: Aave. From an integrator's perspective, Aave is not one protocol. It is three.

Aave V2, V3 and V4 are three generations of the same protocol family, but their onchain structures differ substantially: different field layouts, rate encodings and, in V4, a completely redesigned liquidity architecture. Without normalization, an integrator effectively maintains three separate data and execution integrations. We map all three into one unified record, so downstream code never needs to know which version it is consuming.

This is the story of how those three versions differ, why the differences are bigger than the version numbers suggest, and what it takes to make a V2 rate and a V4 rate directly comparable.

The Shape of the Problem

Here's the same question across the three versions: "How much can I borrow against this collateral, and when do I get liquidated?"

Aave V2 one pool · per-reserve params One LTV per asset One liquidation threshold Stable and variable borrow No caps. No eMode. No isolation. The simplest case. Aave V3 one pool · per-mode params Collateral + liquidation params per eMode category Supply + borrow caps Isolation debt ceilings Siloed borrowing eMode lifts efficiency for correlated assets. Re-derived again in V3.2. Aave V4 Hub & Spoke · per-Spoke One factor for both the borrow and liquidation LTV Hub-level rate utilization Per-Spoke positions + caps User-specific risk premium No stable borrow. Risk lives per Spoke; liquidity lives in the Hub.

One question, three vocabularies. V2 gives you one LTV and one liquidation threshold per asset. V3 gives you collateral and liquidation parameters per eMode category, plus caps, isolation debt ceilings and siloed-borrowing rules, then changes how eMode membership and configuration are derived in V3.2. V4 replaces the layout entirely with a shared Liquidity Hub, Spoke-specific risk environments and one collateral factor in place of separate borrowing and liquidation thresholds.

The differences are bigger than "V2 → V3 → V4" suggests. These aren't incremental field additions. They are three different mental models of what a lending market is. Our job is to map all three into the same schema, where the absence of a feature is a well-defined default rather than a special case you have to code around.

One Model, Three Mappings

Each Aave version is read in its native shape and mapped into one canonical reserve record. Version-specific fields, units and capability differences are resolved in that mapping, producing a stable output contract for downstream consumers.

Aave V2 single pool · stable + variable Aave V3 / V3.2 caps · eMode · isolation Aave V4 Hub & Spoke · risk premium Normalize: rates → one unit · amounts → one scale · utilization → one formula version-specific quirks absorbed here ONE UNIFIED RESERVE RECORD total deposits · total debt · deposit & borrow APR utilization · risk config · caps · flags · rewards

The payoff is that new features don't ripple outward. When V3.2 changed eMode encoding, only the V3 mapping changed. V4 received a separate mapping for its Hub-and-Spoke architecture. Future protocol versions can be supported by adding new mappings without requiring consumers to adopt version-specific response logic.

The Unified Output

Regardless of version, every Aave reserve is returned as one canonical reserve record:

fieldmeaning
marketUidunique market ID (chain + lender + asset)
totalDepositstotal supplied
totalDebttotal variable debt
totalDebtStabletotal stable-rate debt; 0 where unsupported
totalLiquiditycurrently available underlying liquidity
depositRatedeposit APR, percent
variableBorrowRateborrow APR, percent
stableBorrowRatestable borrow APR, percent (0 where unsupported)
utilization0..1
config{}collateral parameters by mode
borrowCap / supplyCap0 = uncapped
debtCeilingisolation-mode limit
collateralActive / borrowingEnabled / depositsEnabled / isActive / isFrozen / hasStableper-reserve flags
intrinsicYieldextra yield (staking / rebasing)
rewards[]incentive APRs

The Comparability Work

Making the shape identical is the easy half. The hard half is making the numbers mean the same thing.

Interest rates: one unit. Aave's contracts expose annualized liquidity and borrow rates in ray-scaled fixed-point form. 1delta returns these as APR percentages by dividing the ray value by 10²⁷ and multiplying by 100; it does not apply a compounding conversion to APY. This method is used consistently across V2, V3 and V4 so the values can be compared directly.

Amounts: one scale. Raw onchain balances are unscaled integers that routinely exceed ordinary number types. We scale each amount by the token's decimals and return it using a lossless decimal representation, avoiding silent rounding across versions.

Utilization: one definition, different scopes. In V2 and V3, utilization is reserve-specific. In V4, base rates are driven by Hub-level utilization pooled across Spokes sharing the asset, while positions, collateral rules, caps and risk remain Spoke-specific.

Features Missing from Older Versions

A missing feature maps to a neutral default paired with an explicit capability flag whenever a zero value could be ambiguous.

FeatureV2V3V4
Supply / borrow capsnone → uncappedper-reserveper-Spoke
eModenone → single default modecategoriesreplaced by dynamic config
Isolation modenonedebt ceilingnot applicable
Stable borrowyesyesremoved → always zero
Debt modelvariable + stablevariable + stablevariable debt with base and premium interest

An uncapped limit reads as 0. A version with no eMode exposes a single default config entry. A version with no stable borrow reports zero and a hasStable: false flag. Neutral defaults keep the record structurally stable, while capability flags distinguish unsupported features from meaningful zero values.

Where Each Version Differs

The abstraction is clean. The protocols behind it are not. Here's what each generation brings.

V2: The Simple Case (with a Long Tail of Forks)

V2 is the easy one: a single pool, no caps, no eMode, no isolation, one LTV and one liquidation threshold per asset. It still has stable borrow, so its stable rate is real, a feature that simply doesn't exist in V4.

The real complexity in V2 isn't Aave V2 itself; it's the ecosystem of forks built on its design: Aurelius, Lendle, Granary, Radiant and others, each with its own reward tokens and incentive quirks layered on top. We fold all of them into the same V2 mapping so they surface as ordinary Aave-shaped reserves.

V3: Caps, eMode, Isolation and a Mid-Life Format Change

V3 is where the per-asset surface expands. On top of the basics, assets can now carry supply and borrow caps, an isolation-mode debt ceiling, a siloed-borrowing rule, as well as collateral and liquidation parameters that can vary by eMode category, the mechanism that lets correlated assets (say, ETH and an ETH liquid-staking token) borrow against each other with much greater efficiency.

Then V3.2 changed how eMode membership and configuration are derived mid-life. An asset that qualified for an eMode under the original layout has to be re-derived under the new one, exactly the kind of change that breaks naïve integrations silently. We absorb both encodings into the same risk-config shape, so from the outside an eMode looks the same whether it came from legacy V3 or V3.2.

V4: A Different Protocol Wearing the Same Name

V4 is not a bigger V3. It's a re-architecture, and it's where most of the interesting complexity lives.

Hub-and-Spoke architecture. A V4 deployment splits into a central Liquidity Hub that holds the actual assets and runs the interest-rate model, alongside many Spokes, each providing a separate position and risk environment that routes liquidity through the Hub. The key idea: liquidity is shared at the Hub, but risk is isolated at the Spoke. Base rates are determined by Hub-level utilization, while positions, collateral composition, health, caps and other risk constraints remain Spoke-specific. The Hub is a shared liquidity layer, not a shared position or risk surface.

Liquidity Hub shared assets · rate model pooled utilization Spoke "Main" own risk · own market Spoke "Lido" own risk · own market Spoke "Kelp" own risk · own market Spoke "Prime" own risk · own market Shared liquidity, isolated risk - each Spoke is its own market.

That architecture requires a 1delta modeling decision: what is a "market" in V4? A Hub cannot represent a user's market exposure because positions and risk are tracked by each Spoke. 1delta therefore models each Spoke as a distinct market context. Two Spokes sharing a Hub remain distinct canonical markets, while their base rates can reflect the same Hub-level utilization.

One collateral factor instead of two thresholds. This is the change most likely to surprise integrators coming from V3. In V3, each asset has a borrow LTV and a separate, higher liquidation threshold. The gap creates an explicit buffer before liquidation. V4 replaces the separate borrowing and liquidation thresholds with one collateral factor.

Aave V3Aave V4
Per-asset thresholdsborrow LTV 75%, liquidation 80% → 5% bufferone factor 80%
Maxing out a borrowbuffer remains before liquidationno separate LTV-to-liquidation-threshold buffer

To keep the unified record consistent, V4 reports the same value for both the borrowing and liquidation factors, so multi-protocol consumers do not need V4-specific handling. The equality should still be surfaced to users. V4 separately prices collateral risk through a user-specific premium added to the shared base borrow rate. We expose the relevant bounds and inputs so integrations can distinguish the shared base rate from position-dependent pricing.

No stable borrow. The concept is gone in V4. Stable debt and the stable rate are always zero, the stable flag is false, and all debt is reported through the variable-debt field.

One-Sentence Takeaway

1delta maps Aave V2, V3 and V4 into one canonical schema, making their markets directly comparable without forcing integrators to maintain version-specific logic.

Where to Go Next

← All posts