Add Unblock Equity yield adapter — 24 vaults on Base#2659
Conversation
UnblockEquity is a tokenized junior-lien home-equity lending protocol on Base.
Depositors fund 24 segmented MetaMorpho vaults (verification × recovery × escrow tier);
borrowers (homeowners) collateralize tokenized property liens (ERC-1155).
TVL adapter for the protocol was merged in DefiLlama-Adapters#19102.
This PR adds the matching yield-server adapter so APYs surface on /yields.
- TVL: live from each vault's totalAssets() (ERC4626)
- APY: modeled equilibrium yield from each vault's published risk model
(PD × LGD → net yield). Matches the displayed APY in the protocol's
earn page and the published risk whitepaper. Live IRM rates are
intentionally NOT used because Morpho's adaptive-curve IRM drifts
toward zero on idle high-utilization markets, which would
misrepresent the long-run yield depositors actually earn.
- Verified: 24/24 vaults addressable, total TVL $11.8K (matches on-chain).
- APY range across 24 pools: 7.50%–9.26%
Adapter URL: https://app.unblockequity.com/earn
DefiLlama protocol page: https://defillama.com/protocol/unblock-equity
📝 WalkthroughWalkthroughAdded a new Unblock Equity yield adapter module for Base chain. The adapter defines 24 vault contracts with hardcoded net yields, fetches live TVL for each vault via ERC-4626 ChangesUnblock Equity Yield Adapter
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
The unblock-equity adapter exports pools: Test Suites: 1 passed, 1 total |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/adaptors/unblock-equity/index.js`:
- Around line 52-76: The code currently swallows all errors in the Promise.all
batch mapper (inside the catch after calling new ethers.Contract(v.vault,
ERC4626_ABI, provider).totalAssets()), turning failures into tvlUsd = 0; to
avoid returning many zero-TVL pools on an RPC-wide outage, add a top-level
failure counter (e.g., failedReads) in the function that increments inside that
catch, and after processing all VAULTS check if failedReads === VAULTS.length
and if so throw or return an error to abort publishing; update the catch to
still set tvlUsd = 0 for individual vaults but ensure you increment failedReads
there so the final guard can detect total RPC failure (refer to symbols:
Promise.all batch map, totalAssets, tvlUsd, VAULTS, pools).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c3d43070-841e-4bbe-8d6e-7474dcd1b99b
📒 Files selected for processing (1)
src/adaptors/unblock-equity/index.js
| const results = await Promise.all(batch.map(async (v) => { | ||
| let tvlUsd = 0; | ||
| try { | ||
| const totalAssets = await new ethers.Contract(v.vault, ERC4626_ABI, provider).totalAssets(); | ||
| tvlUsd = parseFloat(ethers.utils.formatUnits(totalAssets, 6)); | ||
| } catch { | ||
| // Vault unreachable — list with zero TVL, modeled APY still informative | ||
| } | ||
| return { | ||
| pool: `${v.vault.toLowerCase()}-base`, | ||
| chain: "Base", | ||
| project: "unblock-equity", | ||
| symbol: "USDC", | ||
| tvlUsd, | ||
| apyBase: v.netYield, | ||
| underlyingTokens: [USDC], | ||
| url: "https://app.unblockequity.com/earn", | ||
| poolMeta: v.name, | ||
| }; | ||
| })); | ||
| pools.push(...results); | ||
| if (i + 6 < VAULTS.length) await new Promise((r) => setTimeout(r, 300)); | ||
| } | ||
|
|
||
| return pools; |
There was a problem hiding this comment.
Avoid silently publishing zero TVL during RPC-wide failures.
Right now every fetch error is swallowed and converted to tvlUsd = 0. If Base RPC is degraded, this can return 24 “valid-looking” pools with zero TVL, which is misleading data rather than a hard failure.
Suggested guardrail (fail when all vault reads fail)
const pools = [];
+ let totalFailures = 0;
for (let i = 0; i < VAULTS.length; i += 6) {
const batch = VAULTS.slice(i, i + 6);
const results = await Promise.all(batch.map(async (v) => {
let tvlUsd = 0;
+ let failed = false;
try {
const totalAssets = await new ethers.Contract(v.vault, ERC4626_ABI, provider).totalAssets();
tvlUsd = parseFloat(ethers.utils.formatUnits(totalAssets, 6));
} catch {
+ failed = true;
// Vault unreachable — list with zero TVL, modeled APY still informative
}
return {
pool: `${v.vault.toLowerCase()}-base`,
chain: "Base",
project: "unblock-equity",
symbol: "USDC",
tvlUsd,
apyBase: v.netYield,
underlyingTokens: [USDC],
url: "https://app.unblockequity.com/earn",
poolMeta: v.name,
+ _failed: failed,
};
}));
- pools.push(...results);
+ totalFailures += results.filter((r) => r._failed).length;
+ pools.push(...results.map(({ _failed, ...pool }) => pool));
if (i + 6 < VAULTS.length) await new Promise((r) => setTimeout(r, 300));
}
+
+ if (totalFailures === VAULTS.length) {
+ throw new Error("unblock-equity: failed to fetch totalAssets() for all vaults");
+ }
return pools;
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/adaptors/unblock-equity/index.js` around lines 52 - 76, The code
currently swallows all errors in the Promise.all batch mapper (inside the catch
after calling new ethers.Contract(v.vault, ERC4626_ABI,
provider).totalAssets()), turning failures into tvlUsd = 0; to avoid returning
many zero-TVL pools on an RPC-wide outage, add a top-level failure counter
(e.g., failedReads) in the function that increments inside that catch, and after
processing all VAULTS check if failedReads === VAULTS.length and if so throw or
return an error to abort publishing; update the catch to still set tvlUsd = 0
for individual vaults but ensure you increment failedReads there so the final
guard can detect total RPC failure (refer to symbols: Promise.all batch map,
totalAssets, tvlUsd, VAULTS, pools).
|
Polite bump — this has been green for 8 days:
Would appreciate a maintainer look when you have a moment. Happy to address any review feedback. Thanks! |
Adds yield adapter for Unblock Equity — a tokenized junior-lien home-equity lending protocol on Base. Depositors fund 24 segmented MetaMorpho vaults; homeowners borrow USDC against tokenized property liens (ERC-1155).
The TVL adapter was merged earlier this week in DefiLlama-Adapters#19102. This PR adds the matching yield-server entry so APYs surface on the yields page.
What this adapter publishes
{Verification × Recovery × BR}combototalAssets()(ERC4626)pool,chain,project,symbol,tvlUsd,apyBase,underlyingTokens,url,poolMetaWhy not live IRM rates?
Considered using
borrowRateView()from Morpho's IRM, but Morpho's adaptive-curve IRM drifts toward zero on idle high-utilization markets — at the moment of this PR our genesis market shows 0.34% on-chain APY despite 86% utilization, simply because no one has interacted with it for 6 days. The drift is normal IRM behavior but it would misrepresent the long-run yield depositors actually earn.The modeled net yield = expected yield given PD × LGD per the published risk model. It's exactly what's displayed in the protocol's earn page (https://app.unblockequity.com/earn) and what's documented in the risk whitepaper.
Live verification
```
Pools: 24 TVL: $11,876.62
Standard Lien BR12 TVL=$11,876.39 APY=8.03% ← genesis vault (active)
```
Links
Summary by CodeRabbit