Skip to content

fix(ilRisk): don't collapse ETHFI/sETHFI into the ETH family (substring false-match)#2821

Open
Himess wants to merge 1 commit into
DefiLlama:masterfrom
Himess:fix/ilrisk-ethfi-substring
Open

fix(ilRisk): don't collapse ETHFI/sETHFI into the ETH family (substring false-match)#2821
Himess wants to merge 1 commit into
DefiLlama:masterfrom
Himess:fix/ilrisk-ethfi-substring

Conversation

@Himess

@Himess Himess commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

checkIlRisk decides IL risk by substring-matching each token against a hardcoded L1 list. 'ethfi'.includes('eth') is true, so ETHFI collapses into the ETH family. An ETHFI/ETH pool then looks like a single-family pair and gets ilRisk: "no", even though ETHFI is Ether.fi's governance token and uncorrelated with ETH.

11 live pools, $1.54M, are labelled no IL risk when the risk is real:

TVL project symbol
$729,147 uniswap-v4 ETH-ETHFI
$226,226 velodrome-v3 WETH-ETHFI
$123,967 uniswap-v4 ETH-ETHFI
$123,777 uniswap-v4 ETH-ETHFI
$92,410 camelot-v3 ETHFI-WETH
$78,480 velodrome-v2 WETH-ETHFI
$74,733 uniswap-v3 WETH-ETHFI
$32,836 uniswap-v3 ETHFI-WETH
$25,952 uniswap-v4 ETH-SETHFI
$20,934 uniswap-v3 WETH-ETHFI
$15,460 aerodrome-slipstream WETH-ETHFI

The same token gets the right answer when it isn't paired with ETH. USDT-ETHFI is correctly ilRisk: "yes", because there's no L1 for it to collapse into. That isolates the substring collapse.

 const checkIlRisk = (el) => {
   const l1Token = ['btc', 'eth', 'avax', 'matic', 'eur', 'link', 'sushi'];
+  // tokens that merely CONTAIN an l1Token substring but are NOT correlated with it
+  // (independent governance/utility tokens). Without this, e.g. 'ethfi'.includes('eth')
+  // collapses ETHFI into the ETH family and mislabels ETHFI-ETH pools as ilRisk 'no'.
+  const notCorrelated = ['ethfi', 'sethfi', 'ethdydx', 'ethix'];
   const symbol = el.symbol.toLowerCase();
   const tokens = symbol.split('-');
   ...
     const elements = [];
     for (const t of tokens) {
+      if (notCorrelated.includes(t)) continue;
       for (const x of l1Token) {
         if (t.includes(x)) {
           elements.push(x);
           break;
         }
       }
     }

Tested against all 15,410 live pools: exactly 11 flip no to yes, all ETHFI/sETHFI-ETH pairs. 0 flip yes to no. Every changed pool contains an exception token. The change is one-directional by construction: forcing a known-uncorrelated token not to collapse can only add IL-risk flags where they belong, it cannot produce a false "no".

The list needs maintenance as new tokens appear, which isn't ideal. The robust fix is replacing the substring match with a correlated-token family registry. Happy to do that instead if you prefer.

One related thing I found but deliberately did not patch here. The same function marks SOL and BNB liquid-staking pairs as ilRisk: "yes" (SOL-JITOSOL, SOL-MSOL, BNBX-WBNB, 66 pools, about $27.5M) because sol and bnb aren't in l1Token, while the identical ETH relationship (STETH-ETH, WSTETH-ETH) correctly gets "no". I tested adding them to the list and it makes things worse: about 19 memecoins that merely contain "sol" (SOLO, SOLCEX, SOLGOAT, SOLAMA) would wrongly become "no", and substring can't tell them apart from real LSTs like STSOL or EZSOL. So that direction needs the registry, not a list-add. Let me know if you want me to take it on.

Summary by CodeRabbit

  • Bug Fixes
    • Improved impermanent loss risk classification for select tokens.
    • Prevented specific token matches from being incorrectly grouped with broader Layer 1 token families.

checkIlRisk substring-matches each token against a hardcoded L1 list, so
'ethfi'.includes('eth') collapses ETHFI into the ETH family and mislabels
ETHFI/ETH pools as ilRisk "no" (ETHFI is Ether.fi's governance token,
uncorrelated with ETH). Add a notCorrelated exception set so tokens that
merely contain an L1 substring don't collapse. 11 live pools (~$1.54M)
flip to the correct "yes"; 0 regressions across all 15,410 pools.
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8b96c887-8922-4c82-99e0-0898aa99ecc4

📥 Commits

Reviewing files that changed from the base of the PR and between 732246c and 0a317f2.

📒 Files selected for processing (1)
  • src/handlers/triggerEnrichment.js

📝 Walkthrough

Walkthrough

checkIlRisk now excludes selected token identifiers from L1 substring correlation, preventing those tokens from contributing to IL-risk family classification.

Changes

IL-risk correlation handling

Layer / File(s) Summary
Exclude non-correlated tokens
src/handlers/triggerEnrichment.js
Adds a notCorrelated token list and skips matching tokens during correlated-element processing.

Estimated code review effort: 2 (Simple) | ~5 minutes

Suggested reviewers: slasher125, monetrixlab

🚥 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 clearly describes the main fix: preventing ETHFI/sETHFI substring matches from being collapsed into the ETH family.
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.
✨ 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.

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