How Epoch Protocol Added Liquid Lending Yield Through One Integration
Epoch Protocol turns a stated financial outcome into onchain execution across chains and rails. To make idle balances earn, it integrated 1delta once instead of wiring up lending protocols one at a time - reaching 3,420 deposit-open markets across five chains through a single normalized interface.
At a Glance
- Partner: Epoch Protocol, an intent execution layer that lets institutions and product teams define a financial outcome and have it settled across chains, protocols, and payment rails.
- Challenge: Offer yield on idle balances as a first-class outcome, without turning "earn" into a permanent backlog of protocol adapters, one per lender and chain.
- Approach: Integrate the 1delta API as the lending layer behind Epoch's lend intents: one normalized interface for market discovery, deposit execution, and position reads.
- Result: Liquid lending deposits across 3,420 markets currently open for deposits - out of 4,072 indexed markets and 72 distinct lenders - on the five chains where Epoch's network and 1delta's lending coverage overlap.
- Deposits stay liquid: no lock-ups and no fixed terms; every market exposes its available exit liquidity, so a withdrawal is a data question rather than a wait.
Define the Outcome, Epoch Handles the Rails

Epoch Protocol is an execution layer for financial outcomes. The pitch on their site is deliberately narrow: define the outcome, and Epoch handles the chains and rails underneath. A caller states what should be true at the end - this balance, in this asset, on this chain, earning - and Epoch coordinates the routing, bridging, swapping, compliance screening, and settlement needed to get there. From the outside it is one API call and one signature; from the inside it is a multi-leg cross-chain flow.
Underneath, that outcome is decomposed. An intent enters the network with its constraints - approvals, optimization target, deadlines - and sub-intent orchestrators split it into pieces that specialized solvers handle: swap, stake, lend. Observers the protocol calls Hyperions watch onchain conditions and trigger execution when the stated criteria are met, which is what makes recurring and conditional flows possible rather than one-shot transactions. Settlement lands in an ERC-4337 smart account extended with plugins and hooks (ERC-7579, EIP-7702, ERC-7715). The account keeps custody: Epoch holds no signing keys, approvals are scoped and expiring, and a failed leg stops in a known state with funds recoverable rather than stranded mid-route.
The audience follows from that design. Epoch targets banks, fintechs, neobanks, funds, and product teams that want onchain capability without hiring a crypto engineering team - reachable through an embedded widget, a Flows SDK for custom UI, or the Intents SDK and API directly. Mainnet coverage spans Ethereum, Base, Arbitrum, Optimism, Polygon, BNB Chain, and Miden, the last of which backs private settlement.
The Challenge
For a platform whose product is outcomes, "make this balance earn" is an obvious one to support. It is also the one that scales worst if you build it the usual way.
A swap solver can lean on aggregators that already abstract venue fragmentation. Lending has no equivalent by default. Each lender has its own contracts, its own rate encoding, its own accounting for what a deposit even is - an aToken, a cToken, a share in a vault, an internal balance - and its own withdrawal semantics. Multiply that by every chain a deployment exists on and the Lend solver stops being one solver and becomes a directory of them.
The cost is not the first integration. It is that the directory never stops growing and never stops drifting. Every new lender is another adapter; every protocol upgrade is a silent breakage waiting for the next execution. Aave re-encoding eModes in V3.2 mid-life is the standard example - the kind of change that does not announce itself in a type error. For a system built on recurring, condition-triggered flows that run unattended, a data layer that quietly goes stale is worse than one that fails loudly.
There is a second requirement that narrows the field further. Epoch's flows are composable: a lend leg can sit in the middle of a chain of steps, and capital may need to move again when a Hyperion fires. Deposits therefore have to be liquid - redeemable on demand, no fixed term, no lock-up - and the solver has to know before it commits whether the exit liquidity is actually there. Pooled lending markets can be fully utilized; a deposit into one is not automatically a deposit you can leave.
The Approach
Epoch integrated the 1delta API once and made it the lending layer behind its lend intents. From the solver's side it is one HTTPS surface with a single x-api-key header - no nodes to run, no ABIs to track, no per-protocol branch in the execution path.
Three things the solver needs map onto that surface directly:
| What the solver asks | Where it comes from |
|---|---|
| Where should this deposit go? | /v1/data/lending/pools - every market on a chain with depositRate, totalLiquidityUsd, utilization, caps and flags, keyed by a stable marketUid like AAVE_V3:1:0x… |
| Can the user get back out? | The same record carries withdrawLiquidity and depositable, so exit capacity is checked before capital is committed, not after |
| What does the user hold now? | /v1/data/lending/user-positions - deposits and debt per token across every indexed lender, in USD, with a per-lender health factor |
The property that makes this work as a solver dependency, rather than just a data feed, is that every record comes back in the same shape. An Aave V3 reserve, a Compound V3 Comet market, a Morpho Blue market, a Euler vault, and a Silo deployment all arrive as the same pool object with the same fields. Even three generations of one protocol are folded into a single schema, which we covered separately in unifying Aave. Rate comparison becomes arithmetic on one unit instead of a normalization pass; market selection becomes a sort.
That matters more for intents than for a dashboard. A dashboard can afford a special case per protocol because a human reads the output. A solver picking a venue inside an unattended, condition-triggered flow cannot - it needs to rank every candidate market against the same comparable number and commit without a human in the loop. Normalization is the precondition for automation, not a convenience on top of it.
The liquidity requirement is answered by the same records. These are pooled lending deposits with no fixed term: capital goes in, accrues at the market's deposit rate, and comes out on demand as long as the pool has liquidity. Because withdrawLiquidity and utilization are exposed per market, the solver can require headroom before selecting a venue and re-check it before a Hyperion-triggered exit. Liquidity stops being an assumption and becomes a filter. For anything that needs a guaranteed exit date instead, that is the separate world of fixed-term lending.
What "Hundreds of Markets" Actually Means
The 1delta API is queried, not consulted from a table - GET /v1/data/lender-ids currently returns 186 lender deployments, and coverage changes as deployments are added. Querying the pools endpoint on 2026-08-18 across the chains where Epoch's mainnets and 1delta's lending coverage overlap gives the concrete picture:
| Chain | Lenders | Indexed markets | Open for deposits |
|---|---|---|---|
| Ethereum | 51 | 2,141 | 1,733 |
| BNB Chain | 22 | 694 | 648 |
| Base | 17 | 575 | 537 |
| Arbitrum | 21 | 571 | 422 |
| Optimism | 10 | 91 | 80 |
| Total | 72 distinct | 4,072 | 3,420 |
"Open for deposits" counts markets that are active, unfrozen, and accepting supply - the ones a lend solver can actually route into right now. The gap between the two right-hand columns is the part a hand-rolled integration also has to model: a market existing is not the same as a market being usable, and each protocol expresses that differently through pause flags, frozen reserves, and supply caps.
Read the lender column rather than the market column to size the alternative. Reaching those 3,420 deposit venues by hand means 72 separate lender integrations - each with its own contracts, rate encoding, decimals handling, and withdrawal path - re-verified per chain, because the same protocol behaves differently across deployments.
The Work That Did Not Happen
The integration's value shows up mostly as absence. Each row below is work a from-scratch lending layer needs upfront and then keeps needing.
| Work the API absorbs | What building it means |
|---|---|
| Protocol adapters | One integration per lender, then again per chain - 72 of them for today's coverage |
| Rate normalization | Converting each protocol's fixed-point encoding into one comparable APR before a solver can rank anything |
| Amount scaling | Scaling raw balances by token decimals and pricing them for USD-denominated constraints |
| Availability modelling | Reading pause flags, frozen reserves, supply caps, and utilization the way each protocol expresses them |
| Exit liquidity | Deriving per-market withdrawal capacity so a "liquid" deposit is liquid in fact |
| Positions and health | Re-deriving every lender's account data and health-factor definition into one shape |
| Ongoing maintenance | Tracking breaking upgrades so unattended flows do not silently execute against a stale assumption |
The last row is the one that compounds. A hand-rolled lending layer is a standing liability that grows with every protocol and every upgrade, and it grows fastest precisely when the product is succeeding. A normalized dependency is maintained upstream: when a lender ships a breaking change, the absorption happens on the API side, and the next supported chain or deployment arrives without Epoch writing another adapter.
For Epoch specifically, the trade is clean because the lending layer sits below the line where its product competes. Epoch's differentiation is the intent model - decomposition, solver coordination, conditional triggers, smart-account custody, compliance and settlement across rails. Normalized lending data and execution is necessary underneath all of that and is essentially identical for every product that needs it. Spending engineering months on the identical part would have bought nothing a competitor could not also buy, while delaying the part that is genuinely theirs.
[DRAFT - suggested wording. Abhimanyu: confirm, reword, or replace entirely.]
One integration stood in for 72, and it keeps standing in for them: every lender and chain we pick up now arrives without a line of adapter code on our side. For a system that runs unattended flows on other people's balances, the maintenance we never took on matters more than the build we skipped.
Abhimanyu ShekhawatCo-founder, Epoch Protocol
Why It Worked
Three properties of the dependency made it a fit for an intent system rather than merely a convenient data source.
One schema across protocols. Solvers rank candidates automatically. Uniform records make ranking arithmetic instead of a normalization step in the hot path.
Availability as data. Flags, caps, utilization, and withdrawal capacity ride along with the rate, so a solver filters unusable markets before committing capital rather than discovering the problem in a revert.
Coverage that grows without integration work. New lenders and deployments land behind the same endpoints. Epoch's addressable venue set widens without a release on their side.
The transferable version: if a capability is necessary for your product but not where you win, the integration cost is only half the argument. The other half is the maintenance you never take on - every adapter, rate conversion, and breaking upgrade that never reaches your backlog. For a platform running unattended flows on other people's balances, that second half is the larger number.
Where to Go Next
- Epoch Protocol: The intent execution layer featured here - widget, Flows SDK, and Intents API.
- API reference: The
/v1/data/lending/*endpoints andx-api-keysetup behind this integration. Start with/lending/pools. - 1delta docs: Supported lenders and networks, and the rest of the lending documentation.
- Building on the API: A walkthrough of the same surface, from first request to executed position.