How 1delta Makes 3,000+ Onchain Lending Markets Comparable

Why DeFi lending data is difficult to compare across protocols, and how the 1delta API maps more than 3,000 fragmented markets into a single queryable surface.


Illustration for “How 1delta Makes 3,000+ Onchain Lending Markets Comparable”

If you've ever tried to answer a question as simple as "What's the best USDC supply rate right now?" across DeFi lending protocols, you already know the punchline: the question has no clean answer. The rates are onchain. The problem is that every protocol exposes them differently. Different ABIs. Different math. Different units. Different definitions of risk. Different opinions of what a "market" even is.

A single chain (Ethereum) lists 533 lending markets in our index today, spread across Aave V3, Spark, Compound V3, Morpho Blue, Euler V2, Fluid, Silo V2, and a long tail of smaller deployments. Each one is its own integration. None of them speak the same language.

This article is about why that fragmentation exists, why "just compare the APYs" doesn't work, and how the 1delta API turns those 3,000+ disjoint markets into a single queryable surface.

Without an aggregator

Every onchain lender ships its own schema. The fields are named differently, defined differently, and encoded in different units. There's no middle layer, so your application either supports one protocol or builds the normalization itself.

Aave V3 ltv liqThreshold healthFactor eModeCategory borrowCap Compound V3 collateralFact. borrowCollat. liquidateFact. baseTrackApr netCashUsd Morpho Blue lltv (WAD) liqIncentive marketParams borrowShares irmPerSecond Spark ltv liqThreshold dsrRate netAprDsr sDaiBalance Euler V2 borrowLTV liquidationLTV vaultGovernor irmKind unitOfAccount Fluid collateralFact. withdrawalGap borrowMaxAvail dexFee positionT1T2 Your team writes the normalization layer unit conversion · semantic mapping · per-protocol risk math · health-factor reconciliation …re-implemented every time a new lender ships Your App

The fragmentation has three dimensions:

1. Fragmented Protocol Models

"DeFi lending" is no longer a single product category with a few implementations. It now encompasses several fundamentally different architectures that happen to share the words deposit, borrow, collateral. Aave V3 is a multi-asset cross-margin pool. Morpho Blue is a registry of isolated (collateral, debt) markets. Spark is a CDP attached to a savings rate. Euler V2 is a vault factory. Fluid splits collateral and debt into separate ledgers. Integrating one is roughly the cost of integrating any other - and the long tail keeps growing.

2. Cross-Margin vs. Isolated Markets

The deepest fork is between cross-margin and isolated market designs.

Cross-margin - one shared pool Aave · Compound · Spark WETH USDC wstETH USDT One health factor across every asset Isolated markets - one pair each Morpho Blue · Lista · Fluid · Silo V2 wstETH ↓ USDC cbBTC ↓ USDC WBTC ↓ USDC PT-sUSDe ↓ DAI rETH ↓ WETH weETH ↓ USDC sUSDe ↓ USDT ↓ … A separate health factor per market

In a cross-margin protocol (Aave V3, Compound V2/V3, Spark, Fluid), every asset you deposit contributes to one shared collateral pot, and every asset you borrow draws from it. There's a single health factor and a single liquidation event. The market is the protocol.

In an isolated protocol (Morpho Blue, Euler V2 vaults, Silo V2), each (collateral, debt) pair is its own market with its own oracle, its own interest-rate model, its own LLTV, its own liquidation. The market is the pair. On Ethereum we currently index dozens of distinct Morpho Blue markets - Morpho wstETH-USDT, Morpho cbBTC-USDC, Morpho WBTC-USDC, each $200M–$700M TVL on its own.

These two designs aren't returning the same data because they aren't modeling the same thing. A "supply rate for USDC on Morpho" isn't well-defined: there are dozens of Morpho USDC markets, each with a different collateral asset or loan asset and risk profile. Aave's "supply rate for USDC" is one number per network.

3. Same Terms, Different Math

Even where the protocols do model the same concept, they don't agree on how to name or compute it.

ConceptAaveCompoundMorpho Blue
Max borrow against a unit of collateralLTVCollateral FactorLLTV
Level at which liquidation can fireLiquidation Threshold (separate from LTV)same as Collateral Factorsame as LLTV
Penalty paid by the borrower at liquidationLiquidation Bonus (paid to liquidator)Liquidation IncentiveLiquidation Incentive Factor (different formula)
Per-asset cap on supply / borrowsupplyCap / borrowCap (token units)supplyCap onlyper-market, implicit in IRM
Interest accrual unitpercent APY per secondper-block rateper-second WAD rate
What "net" yield means after rewards & costsnet APR including incentivesbase + tracking APRbase only (rewards via curators)

An integrator who normalizes only the names (e.g. relabels Aave's liquidationThreshold as collateralFactor) creates a dangerous abstraction: Aave's LTV and Liquidation Threshold are different numbers, and pretending they're the same as Compound's collateral factor will mis-estimate how close a position is to liquidation by hundreds of basis points.

This is what we mean by non-unified data. The fields don't just have different names; they have different definitions.

With the 1delta API

We defined one canonical response schema: LendingMarket. It includes an opinionated mapping from every supported protocol. Every numeric field uses the same unit and calculation method, regardless of where the market originated.

Aave V3 Compound V3 Morpho Blue Spark Euler V2 Fluid 1delta UNIFIED · API LendingMarket - one schema, every market config.collateralFactor - max borrow as fraction of collateral · 0..1 config.liquidationThreshold - fraction at which liquidation fires · 0..1 config.liquidationIncentive - bonus paid to the liquidator · 0..1 depositRate · variableBorrowRate - APR · percent utilization · totalLiquidityUsd · risk.score - uniform units, uniform scale Your App

Three things this gives you that the raw protocols don't:

  • A universal handle. Every market is keyed by (chainId, lenderKey, underlying). An Aave V3 cross-margin entry and a Morpho Blue isolated market live in the same address space, even though one is a 12-asset shared pool and the other is a single isolated pair.
  • Unit-normalized numbers. APR is always in percent. Utilization is always in [0, 1]. USD values are priced through one shared oracle, so two pools aren't being compared at two different USDC prices. Per-block rates, RAY, WAD, and per-second WAD are normalized once by the API.
  • A unified risk surface. Aave's split (LTV, Liquidation Threshold), Compound's (Collateral Factor, Liquidation Factor), and Morpho's single LLTV collapse into the same (config.collateralFactor, config.liquidationThreshold, config.liquidationIncentive) triple, with the protocol-specific quirks normalized out. A health factor is therefore comparable across protocols.

What this looks like in practice

The lending data surface lives under /v1/data/lending/. Three endpoints carry most of it:

A lender enumeration endpoint returns every (chainId, lenderKey) pair we index on the chains you ask for, sorted by TVL. Ethereum returns 533 entries today - Aave V3 at the top with $11.2B, Spark at $3.0B, then a long tail of Morpho Blue isolated markets, Compound V3 deployments, Euler V2 vaults, and so on.

A latest-data endpoint takes a page of those lender keys and returns one flat array of unified market items. A WETH market in Aave V3 and a WETH market in Compound V3 come back as two entries with the same field names, the same units, and the same risk-score scale - even though under the hood one is IPool.getReserveData and the other is Comet.getAssetInfo.

A pools endpoint pre-filters and pre-sorts across all of them in one call. "USDC supply opportunities above $1M TVL, paying more than 4% APR, with risk score 3 or better" is one request - not seven SDKs and a normalization layer you write yourself.

Why this matters beyond data

Unified data unlocks unified actions. Once a position on Aave and a position on Morpho Blue look the same to your code, you can do things that previously required custom integration per pair:

  • Optimize across protocols. Find the cheapest borrowing rate and highest supply yield for a target leverage across every lender we index, not just within one.
  • Migrate atomically. A withdrawal from Aave → deposit into Compound → borrow on Compound → repay Aave sequence becomes a single signed transaction through the Composer.
  • Compare apples to apples in your UI. Health factors, liquidation prices, and net APRs are computed from the same fields, so a "Position" row in your front end does not misrepresent the relative risk of a Morpho position compared with an Aave position.

The fragmentation isn't going away. Every new credit primitive in DeFi makes the surface area larger, not smaller. But it doesn't have to be your integration team's problem.

Where to go next

  • API reference - endpoints, response schemas, and API-key authentication.
  • Documentation - narrative guides, supported protocols, and network coverage.
  • The rest of this series digs into looping, atomic migrations, and the Composer contract that makes the cross-protocol actions atomic.
← All posts