You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#2821 and #2822 each fix one token misclassification, but they share a single root cause: both checkStablecoin and checkIlRisk decide what a token is by substring-matching the pool symbol against a hand-curated list. Any volatile token whose symbol merely contains a listed substring gets mislabeled. This issue proposes fixing the class once instead of patching symbols one by one.
Reverse false yes: sol is not in the list, so SOL LST pairs (jitoSOL, mSOL, bSOL) report ilRisk: yes even though they are SOL-correlated with minimal IL. Live sample: 93 jitoSOL/mSOL/bSOL pairs, about $29.8m, all ilRisk: yes. Not fixed, because adding sol to the list would then bucket memecoins like SOLO or SOLCEX by the same substring.
checkStablecoin (src/adaptors/checkStablecoin.js) substring-matches against the ~410 symbol list from https://stablecoins.llama.fi (many short entries: feth, ern, uno, use, cash, hai, vai):
A control sweep found about 25 distinct symbols mislabeled the same way (CASHFROG-USDT, POGAI-USDT, USDC-XYO, LANTERNSOL, and more), so a fixed exception list is a stopgap rather than the fix.
Why they are one bug
Both classifiers read a token's nature from characters in its symbol, not from the token itself. The failure mode is identical (substring collision), and the current patch pattern (exception arrays: notCorrelated in #2821, notStable in #2822) can only remove known-wrong flags one symbol at a time while the false-positive tail keeps growing.
Proposed direction
Classify from each pool's underlyingTokens (contract addresses), which are populated on essentially every pool today (15,373 of 15,376), against a small shared registry instead of by symbol substring:
a pegged-USD address set for checkStablecoin
correlated-asset groups (ETH LSTs, SOL LSTs, BTC wrappers) for checkIlRisk
This resolves the whole class at once: the 93 SOL-LST ilRisk pairs and the memecoin-USDC stablecoin pairs all carry real underlying addresses, so they classify correctly, and the set self-maintains as new tokens reuse the same addresses.
Honest caveats:
A few pools report a placeholder underlying (for example the top pufETH staking pool lists underlyingTokens: ["0x0000000000000000000000000000000000000000"]), so the symbol path has to stay as a fallback and a small symbol-level exception set is still needed for those.
A registry is more upfront work than another exception line, and it needs an owner to keep current.
The actual decision
Keep extending the centralized exception arrays (notCorrelated / notStable). Tiny, safe, one-directional, but whack-a-mole as the tail grows.
Move both classifiers to an address-based registry with a symbol fallback. Removes the class, more upfront cost, needs maintenance.
Offer
I have the reproduction and evidence for both functions and I am happy to build whichever direction you prefer. I can fold #2821 and #2822 into the registry approach, or leave them as the targeted patches and just extend the exception lists. A steer on which you would merge would let me put up the right PR.
Summary
#2821 and #2822 each fix one token misclassification, but they share a single root cause: both
checkStablecoinandcheckIlRiskdecide what a token is by substring-matching the pool symbol against a hand-curated list. Any volatile token whose symbol merely contains a listed substring gets mislabeled. This issue proposes fixing the class once instead of patching symbols one by one.Two symptoms, both live today
checkIlRisk (
src/handlers/triggerEnrichment.js) matches token names againstl1Token = ['btc', 'eth', 'avax', 'matic', 'eur', 'link', 'sushi']:no:'ethfi'.includes('eth')buckets Ether.fi's ETHFI as ETH, so ETH/ETHFI pairs collapse to a single asset and reportilRisk: no. Narrowly fixed in fix(ilRisk): don't collapse ETHFI/sETHFI into the ETH family (substring false-match) #2821.yes:solis not in the list, so SOL LST pairs (jitoSOL, mSOL, bSOL) reportilRisk: yeseven though they are SOL-correlated with minimal IL. Live sample: 93 jitoSOL/mSOL/bSOL pairs, about $29.8m, allilRisk: yes. Not fixed, because addingsolto the list would then bucket memecoins like SOLO or SOLCEX by the same substring.checkStablecoin (
src/adaptors/checkStablecoin.js) substring-matches against the ~410 symbol list from https://stablecoins.llama.fi (many short entries:feth,ern,uno,use,cash,hai,vai):'pufeth'.includes('feth')flags Puffer's restaked-ETH pufETH as a stablecoin. Live: top pool $46.1m,stablecoin: true. Narrowly patched in fix(checkStablecoin): don't flag pufETH/LanternSOL/SUNOLD as stablecoins (substring false-match) #2822.Why they are one bug
Both classifiers read a token's nature from characters in its symbol, not from the token itself. The failure mode is identical (substring collision), and the current patch pattern (exception arrays:
notCorrelatedin #2821,notStablein #2822) can only remove known-wrong flags one symbol at a time while the false-positive tail keeps growing.Proposed direction
Classify from each pool's
underlyingTokens(contract addresses), which are populated on essentially every pool today (15,373 of 15,376), against a small shared registry instead of by symbol substring:checkStablecoincheckIlRiskThis resolves the whole class at once: the 93 SOL-LST ilRisk pairs and the memecoin-USDC stablecoin pairs all carry real underlying addresses, so they classify correctly, and the set self-maintains as new tokens reuse the same addresses.
Honest caveats:
underlyingTokens: ["0x0000000000000000000000000000000000000000"]), so the symbol path has to stay as a fallback and a small symbol-level exception set is still needed for those.The actual decision
notCorrelated/notStable). Tiny, safe, one-directional, but whack-a-mole as the tail grows.Offer
I have the reproduction and evidence for both functions and I am happy to build whichever direction you prefer. I can fold #2821 and #2822 into the registry approach, or leave them as the targeted patches and just extend the exception lists. A steer on which you would merge would let me put up the right PR.
Reproduces from https://yields.llama.fi/pools plus the two functions, 2026-07-16.