Skip to content

morpho-blue: use 1d-realized APY and drop spike snapshots#2686

Open
0xkr3p wants to merge 1 commit into
DefiLlama:masterfrom
0xkr3p:fix/morpho-blue-apy-spike-filter
Open

morpho-blue: use 1d-realized APY and drop spike snapshots#2686
0xkr3p wants to merge 1 commit into
DefiLlama:masterfrom
0xkr3p:fix/morpho-blue-apy-spike-filter

Conversation

@0xkr3p
Copy link
Copy Markdown
Contributor

@0xkr3p 0xkr3p commented May 15, 2026

Adapter recorded Morpho's instantaneous netApy, which briefly spikes when underlying markets hit ~100% utilization. Switch to avgNetApy(lookback: ONE_DAY) for both base and net, and drop pools whose 1d-realized reading exceeds 200% — broken liquidity adapters return constant 1000%+ values across every Morpho field.

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Updated APY calculations for Morpho Blue vaults with refined daily component processing
    • Implemented APY validation to filter non-finite values and prevent unreasonably high rates (>200%) from displaying
    • Enhanced reward token calculation logic with improved negligibility thresholds

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

Warning

Rate limit exceeded

@0xkr3p has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 36 minutes and 50 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5f529942-9813-4ef4-ac90-3133fe50ec2f

📥 Commits

Reviewing files that changed from the base of the PR and between 2b5fd78 and 09e1df1.

📒 Files selected for processing (1)
  • src/adaptors/morpho-blue/index.js
📝 Walkthrough

Walkthrough

This PR refactors the Morpho Blue yield adapter to query and sanitize daily APY components (netApyDay, baseApyDay) from the GraphQL schema, then uses sanitized values to recompute apyBase and apyReward for both Vault V2 and Vault V1 pools while detecting negligible rewards and applying override logic.

Changes

Morpho Blue APY Refactoring

Layer / File(s) Summary
GraphQL schema updates and APY sanitization
src/adaptors/morpho-blue/index.js
MetaMorpho/Vault V1 and Vault V2 GraphQL queries updated to request netApyDay and baseApyDay instead of prior APY fields. New sanitizeApyPct utility returns null for non-finite values and APY exceeding 200%, otherwise converts to percentage form.
Vault V2 pool construction refactoring
src/adaptors/morpho-blue/index.js
buildVaultV2Pools now computes apyBase and apyReward from sanitized daily APY, sums reward APRs, treats rewards as negligible when under 1% of net APY, conditionally populates rewardTokens, and filters null outputs.
Vault V1 pool transformation refactoring
src/adaptors/morpho-blue/index.js
earnV1Pools replaced with new logic: derives base/reward APY from sanitized daily values, applies OP override using new units, selects reward tokens from allocation market APRs, and preserves pool id/url/underlying/pricePerShare fields.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 A rabbit hops through APY fields so green,
Sanitizing numbers—no 200% scene!
Morpho's vaults now compute with care,
Daily splits of base and rewards fair,
Negligible no more, the reward dance plays true.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'morpho-blue: use 1d-realized APY and drop spike snapshots' accurately and specifically summarizes the main change: replacing instantaneous APY with 1-day average APY and filtering out APY spikes above 200%.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

The morpho-blue adapter exports pools:

Test Suites: 1 passed, 1 total
Tests: 8733 passed, 8733 total
Snapshots: 0 total
Time: 1.544 s
Ran all test suites.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/adaptors/morpho-blue/index.js (1)

151-152: ⚡ Quick win

V2 query fetches baseApyDay but never reads it.

buildVaultV2Pools only consumes vault.netApyDay (line 261) and derives apyBase as netApy - rewardComponent * 100 (line 279). The baseApyDay alias added at line 152 is unused, so this either wastes a GraphQL field or — more likely — was intended to drive apyBase directly (which would also make V2 consistent with the V1 path that uses sanitizeApyPct(vault.state.baseApyDay)).

Either drop baseApyDay from the query, or use it in V2 the same way V1 does and reserve the netApy - rewardComponent arithmetic for back-checking the split.

🤖 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/morpho-blue/index.js` around lines 151 - 152, The V2 query adds
baseApyDay but nothing reads it; update buildVaultV2Pools to use the fetched
vault.baseApyDay for apyBase (mirroring V1's
sanitizeApyPct(vault.state.baseApyDay)) instead of computing apyBase as netApy -
rewardComponent*100, and keep the netApy - rewardComponent arithmetic only for a
sanity check or remove baseApyDay from the GraphQL query entirely — adjust the
code paths that reference apyBase (and function sanitizeApyPct) so V2 consumes
vault.baseApyDay consistently.
🤖 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/morpho-blue/index.js`:
- Around line 398-409: The pool shaping logic in the Morpho Blue adaptor can
return non-empty reward tokens with a zero `apyReward` when
`vault.state.netApyDay` is missing, which creates a misleading result. Update
the `buildVaultV1Pools` flow around `sanitizeApyPct`, `isNegligibleApy`,
`rewardTokens`, and `apyReward` so the missing-`netApy` case is handled
consistently: either skip returning the pool when `netApy` is null like
`buildVaultV2Pools` does, or force the no-net case to behave as negligible so
`rewardTokens` stays empty and the APY fields remain aligned.

---

Nitpick comments:
In `@src/adaptors/morpho-blue/index.js`:
- Around line 151-152: The V2 query adds baseApyDay but nothing reads it; update
buildVaultV2Pools to use the fetched vault.baseApyDay for apyBase (mirroring
V1's sanitizeApyPct(vault.state.baseApyDay)) instead of computing apyBase as
netApy - rewardComponent*100, and keep the netApy - rewardComponent arithmetic
only for a sanity check or remove baseApyDay from the GraphQL query entirely —
adjust the code paths that reference apyBase (and function sanitizeApyPct) so V2
consumes vault.baseApyDay consistently.
🪄 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: afefd1e4-b28f-4d21-b5f5-5d9bd527cb6c

📥 Commits

Reviewing files that changed from the base of the PR and between 840cb76 and 2b5fd78.

📒 Files selected for processing (1)
  • src/adaptors/morpho-blue/index.js

Comment thread src/adaptors/morpho-blue/index.js
Adapter recorded Morpho's instantaneous netApy, which briefly spikes when
underlying markets hit ~100% utilization. Switch to avgNetApy(lookback:
ONE_DAY) for both base and net, and drop pools whose 1d-realized reading
exceeds 200% — broken liquidity adapters return constant 1000%+ values
across every Morpho field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@0xkr3p 0xkr3p force-pushed the fix/morpho-blue-apy-spike-filter branch from 2b5fd78 to 09e1df1 Compare May 15, 2026 19:39
@github-actions
Copy link
Copy Markdown

The morpho-blue adapter exports pools:

Test Suites: 1 passed, 1 total
Tests: 8726 passed, 8726 total
Snapshots: 0 total
Time: 1.562 s
Ran all test suites.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant