Skip to content

fix: superstate and switch to stable 30d base w/7day#2281

Merged
0xkr3p merged 1 commit intoDefiLlama:masterfrom
0xkr3p:fix/superstate-uscc-spikes
Jan 22, 2026
Merged

fix: superstate and switch to stable 30d base w/7day#2281
0xkr3p merged 1 commit intoDefiLlama:masterfrom
0xkr3p:fix/superstate-uscc-spikes

Conversation

@0xkr3p
Copy link
Contributor

@0xkr3p 0xkr3p commented Jan 22, 2026

superstate oracle downtime is causing spikes in the yield apr. updated to use 30d base and 7d which aligns with their api results:
https://api.superstate.com/v1/funds/2/yield

{
  "as_of_date": "2026-01-20",
  "thirty_day": 0.05583976567621802,
  "seven_day": 0.09774253329485397,
  "one_day": 0.41382092032231566
}

this should give a smoother more realistic representation of the yield

Summary by CodeRabbit

Release Notes

  • New Features
    • Enhanced APY calculations with multi-window analysis: now provides both 7-day and 30-day perspectives for more comprehensive yield tracking.
    • Added apyBase7d field to display 7-day annual percentage yield.
    • Updated apyBase to reflect 30-day APR for more stable baseline metrics.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 22, 2026

📝 Walkthrough

Walkthrough

The change modifies the APY calculation logic in the Superstate USCC adaptor to use multi-date windows (7-day and 30-day periods) instead of single-day lookups. It introduces new exchange rate retrievals for these periods, calculates apr7d and apr30d with appropriate scaling factors, and updates the returned pool objects to include apyBase7d while setting apyBase to use the 30-day APR value.

Changes

Cohort / File(s) Summary
APY Multi-Window Calculation
src/adaptors/superstate-uscc/index.js
Replaced blockYesterday with block7daysAgo and block30daysAgo; added retrievals of exchangeRate7daysAgo and exchangeRate30daysAgo from USCC oracle; introduced apr7d and apr30d calculations scaled by (365/7) and (365/30) respectively; updated return objects with new apyBase7d field and changed apyBase to use apr30d (30-day APR); normalized all exchange rate values by division with 1e6.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 Hop through seven days and thirty more,
Where oracle rates reveal their store,
Two windows open, calculations divine,
APY blooms across the timeline!
A rabbit's gift of precision refined. 🎯

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title relates to the main change (switching to 30-day base with 7-day value) but uses abbreviated, non-standard language that may not be immediately clear to teammates unfamiliar with the context.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

@llamatester
Copy link

The superstate-uscc adapter exports pools:

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

Nb of pools: 3
 

Sample pools:
┌─────────┬────────────────────────────────────────────────┬─────────────────┬───────────────────┬────────┬──────────────────┬───────────────────┬────────────────────┐
│ (index) │ pool                                           │ chain           │ project           │ symbol │ apyBase          │ apyBase7d         │ tvlUsd             │
├─────────┼────────────────────────────────────────────────┼─────────────────┼───────────────────┼────────┼──────────────────┼───────────────────┼────────────────────┤
│ 0       │ '0x14d60e7fdc0d71d8611742720e4c50e7a974020c'   │ 'ethereum'      │ 'superstate-uscc' │ 'USCC' │ 5.68601041806989 │ 9.934463978351342 │ 327701297.7837047  │
│ 1       │ 'BTRR3sj1Bn2ZjuemgbeQ6SCtf84iXS81CS7UDTSxUCaK' │ 'solana'        │ 'superstate-uscc' │ 'USCC' │ 5.68601041806989 │ 9.934463978351342 │ 15904913.012958577 │
│ 2       │ '0x4c21b7577c8fe8b0b0669165ee7c8f67fa1454cf'   │ 'plume_mainnet' │ 'superstate-uscc' │ 'USCC' │ 5.68601041806989 │ 9.934463978351342 │ 5962075.18323901   │
└─────────┴────────────────────────────────────────────────┴─────────────────┴───────────────────┴────────┴──────────────────┴───────────────────┴────────────────────┘

Copy link

@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

🤖 Fix all issues with AI agents
In `@src/adaptors/superstate-uscc/index.js`:
- Around line 64-67: The APR calculations for apr7d and apr30d can produce
Infinity/NaN when exchangeRate7daysAgo or exchangeRate30daysAgo are 0 or
non-finite; update the logic in the apr7d/apr30d computation to first validate
the historic rates (exchangeRate7daysAgo and exchangeRate30daysAgo) using
Number.isFinite(...) and !== 0, and if invalid return the safe fallback expected
downstream (choose null or 0 consistently), otherwise compute the APR as before;
ensure the same guard is applied to both apr7d and apr30d so neither division
can produce Infinity/NaN.
🧹 Nitpick comments (1)
src/adaptors/superstate-uscc/index.js (1)

27-37: Parallelize block lookups and add request timeouts.

These three sequential HTTP calls add unnecessary latency and create a single point of failure if the endpoint stalls. Parallelizing with Promise.all and adding explicit timeouts will keep the function responsive and aligned with existing timeout patterns in the codebase (e.g., 10-second defaults used elsewhere).

♻️ Proposed refactor
-    const blockNow = (
-        await axios.get(`https://coins.llama.fi/block/ethereum/${timestampNow}`)
-    ).data.height;
-
-    const block7daysAgo = (
-        await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp7daysAgo}`)
-    ).data.height;
-
-    const block30daysAgo = (
-        await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp30daysAgo}`)
-    ).data.height;
+    const [
+        blockNowRes,
+        block7daysAgoRes,
+        block30daysAgoRes,
+    ] = await Promise.all([
+        axios.get(`https://coins.llama.fi/block/ethereum/${timestampNow}`, { timeout: 10_000 }),
+        axios.get(`https://coins.llama.fi/block/ethereum/${timestamp7daysAgo}`, { timeout: 10_000 }),
+        axios.get(`https://coins.llama.fi/block/ethereum/${timestamp30daysAgo}`, { timeout: 10_000 }),
+    ]);
+
+    const blockNow = blockNowRes.data.height;
+    const block7daysAgo = block7daysAgoRes.data.height;
+    const block30daysAgo = block30daysAgoRes.data.height;

Comment on lines +64 to +67
const apr7d = ((exchangeRateToday - exchangeRate7daysAgo) / exchangeRate7daysAgo) *
(365 / 7) * 100;
const apr30d = ((exchangeRateToday - exchangeRate30daysAgo) / exchangeRate30daysAgo) *
(365 / 30) * 100;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard against zero/invalid historic rates to prevent Infinity/NaN APRs.
If the oracle returns 0 or a non-finite value (e.g., during downtime), the current math yields spikes or NaNs—exactly what this PR aims to prevent. Add a safety check and return a safe fallback (e.g., null or 0) aligned with downstream expectations.

✅ Proposed safety guard
-    const apr7d = ((exchangeRateToday - exchangeRate7daysAgo) / exchangeRate7daysAgo) *
-        (365 / 7) * 100;
-    const apr30d = ((exchangeRateToday - exchangeRate30daysAgo) / exchangeRate30daysAgo) *
-        (365 / 30) * 100;
+    const apr7d =
+        exchangeRate7daysAgo > 0
+            ? ((exchangeRateToday - exchangeRate7daysAgo) / exchangeRate7daysAgo) *
+              (365 / 7) * 100
+            : null;
+    const apr30d =
+        exchangeRate30daysAgo > 0
+            ? ((exchangeRateToday - exchangeRate30daysAgo) / exchangeRate30daysAgo) *
+              (365 / 30) * 100
+            : null;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const apr7d = ((exchangeRateToday - exchangeRate7daysAgo) / exchangeRate7daysAgo) *
(365 / 7) * 100;
const apr30d = ((exchangeRateToday - exchangeRate30daysAgo) / exchangeRate30daysAgo) *
(365 / 30) * 100;
const apr7d =
exchangeRate7daysAgo > 0
? ((exchangeRateToday - exchangeRate7daysAgo) / exchangeRate7daysAgo) *
(365 / 7) * 100
: null;
const apr30d =
exchangeRate30daysAgo > 0
? ((exchangeRateToday - exchangeRate30daysAgo) / exchangeRate30daysAgo) *
(365 / 30) * 100
: null;
🤖 Prompt for AI Agents
In `@src/adaptors/superstate-uscc/index.js` around lines 64 - 67, The APR
calculations for apr7d and apr30d can produce Infinity/NaN when
exchangeRate7daysAgo or exchangeRate30daysAgo are 0 or non-finite; update the
logic in the apr7d/apr30d computation to first validate the historic rates
(exchangeRate7daysAgo and exchangeRate30daysAgo) using Number.isFinite(...) and
!== 0, and if invalid return the safe fallback expected downstream (choose null
or 0 consistently), otherwise compute the APR as before; ensure the same guard
is applied to both apr7d and apr30d so neither division can produce
Infinity/NaN.

@0xkr3p 0xkr3p merged commit 1ce965e into DefiLlama:master Jan 22, 2026
2 checks passed
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.

2 participants