Skip to content

Conversation

0xNx
Copy link
Contributor

@0xNx 0xNx commented Aug 27, 2025

Fix SparkDEX V3 and V3.1 adapters for proper DefiLlama integration

Summary

This PR fixes critical issues in SparkDEX V3 and V3.1 adapters that were preventing pools from appearing on DefiLlama's combined page. The main issues were incorrect chain naming and APY calculation problems.

Issues Fixed

1. Chain Name Mismatch 🚨

  • Problem: Both V3 and V3.1 adapters used chain: 'Flare' (capitalized)
  • Impact: DefiLlama couldn't recognize these pools as belonging to the Flare chain
  • Solution: Changed to chain: 'flare' (lowercase) to match DefiLlama's standard

2. APY Calculation Issues 🚨

  • Problem: Extremely high APR values caused APY calculations to produce infinite or extremely large numbers
  • Impact: Invalid APY values that could break DefiLlama's display
  • Solution: Added APY capping logic to prevent values exceeding 10000%

3. V3 Adapter Migration 🔄

  • Problem: V3 adapter was using deprecated FlareMetrics API
  • Solution: Migrated to official SparkDEX API for consistency and better data quality

Changes Made

SparkDEX V3 Adapter (src/adaptors/sparkdex-v3/index.js)

- const chain = 'Flare';
+ const chain = 'flare';

- // Old FlareMetrics API implementation
- const utils = require('../utils');
- function getLPPage(limit, offset) { ... }
- function makePoolFlatmap(now, flrPrice) { ... }

+ // New official API implementation
+ const pools = await axios.get(
+   'https://api.sparkdex.ai/dex/v3/pairs?chainId=14&dex=SparkDEX&version=v3'
+ );

+ // APY calculation with safety caps
+ const calculateApy = (_apr) => {
+   if (_apr > 10000) return 10000;
+   // ... rest of calculation with Math.min(APYPercentage, 10000)
+ };

SparkDEX V3.1 Adapter (src/adaptors/sparkdex-v3.1/index.js)

- const chain = 'Flare';
+ const chain = 'flare';

+ // Enhanced APY calculation with safety caps
+ const calculateApy = (_apr) => {
+   if (_apr > 10000) return 10000;
+   // ... rest of calculation with Math.min(APYPercentage, 10000)
+ };

Technical Details

APY Calculation Safety

const calculateApy = (_apr) => {
  // Handle extremely high APR values that could cause calculation issues
  if (_apr > 10000) { // If APR > 10000%, cap it to prevent extreme values
    return 10000;
  }
  
  const APR = _apr / 100;
  const n = 365;

  // APY calculation
  const APY = (1 + APR / n) ** n - 1;
  const APYPercentage = APY * 100;

  // Cap APY to reasonable maximum (10000%)
  return Math.min(APYPercentage, 10000);
};

Data Source Migration

  • V3: Migrated from FlareMetrics API to official SparkDEX API
  • V3.1: Already using official API, enhanced with safety features
  • V2: Unchanged, using Goldsky subgraph

Testing Results

Before Fix

  • ❌ V3.1 pools not visible on DefiLlama combined page
  • ❌ APY values showing as Infinity or extremely large numbers
  • ❌ Chain name mismatch causing classification issues

After Fix

  • ✅ V3.1: 123 pools, 841 tests passed
  • ✅ V3: 2 pools, 18 tests passed
  • ✅ V2: 63 pools, 382 tests passed
  • ✅ All adapters use correct flare chain name
  • ✅ APY values properly capped at 10000%

Impact

DefiLlama Integration

  • Combined page: V3.1 pools now properly visible
  • Chain filtering: All SparkDEX pools correctly categorized under Flare
  • APY display: Reasonable APY values that don't break the UI

Data Quality

  • Consistency: All adapters now use official APIs where possible
  • Reliability: APY calculations protected against extreme values
  • Maintainability: Unified code structure across V3 and V3.1

Files Modified

  • src/adaptors/sparkdex-v3/index.js - Complete rewrite with new API and fixes
  • src/adaptors/sparkdex-v3.1/index.js - Chain name fix and APY safety

Files Unchanged

  • src/adaptors/sparkdex-v2/index.js - Already working correctly

Testing

All adapters pass comprehensive tests:

  • ✅ Field validation
  • ✅ Data type checks
  • ✅ APY calculations
  • ✅ Token validation
  • ✅ Pool uniqueness

Breaking Changes

None. This is a bug fix that improves compatibility with DefiLlama.

Related Issues

  • Fixes issue where V3.1 pools were not visible on DefiLlama combined page
  • Resolves APY calculation errors causing display issues
  • Improves data consistency across all SparkDEX adapters

Deployment Notes

  • No database migrations required
  • Changes are backward compatible
  • DefiLlama will automatically pick up the corrected data format
  • May take some time for changes to propagate to DefiLlama's systems

Future Considerations

  • Monitor APY capping thresholds for different protocols
  • Consider adding more sophisticated APY validation
  • Evaluate if other adapters need similar chain name standardization

Reviewers: Please verify the chain name changes and APY calculation logic
Testing: All adapters pass tests, but manual verification on DefiLlama is recommended

@llamatester
Copy link

The sparkdex-v3.1 adapter exports pools:

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

Nb of pools: 123
 

Sample pools:
┌─────────┬────────────────────────────────────────────────────┬────────────────┬─────────────────┬─────────┬────────────────────┬──────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────────────────────────────────────┐
│ (index) │ pool                                               │ symbol         │ project         │ chain   │ tvlUsd             │ apyBase              │ underlyingTokens                                                                               │ apyReward          │ rewardTokens                                     │
├─────────┼────────────────────────────────────────────────────┼────────────────┼─────────────────┼─────────┼────────────────────┼──────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────────────────────────────────────┤
│ 0       │ '0x0b40111b4cf6dd1001f36f9c631956fefa56bc3b-flare' │ 'USD₮0-USDC.e' │ 'sparkdex-v3.1' │ 'flare' │ 54482428.82512976  │ 0.049020290226318354 │ [ '0xe7cd86e13ac4309349f30b3435a9d337750fc82d', '0xfbda5f676cb37624f28265a144a48b0d6e87d3b6' ] │ 15.291241735302163 │ [ '0x26d460c3Cf931Fb2014FA436a49e3Af08619810e' ] │
│ 1       │ '0x99ed6dfd982d4b3ddd726625a585a3b019523bbb-flare' │ 'USD₮0-cUSDX'  │ 'sparkdex-v3.1' │ 'flare' │ 7396889.032218132  │ 0.005718279164296285 │ [ '0xe7cd86e13ac4309349f30b3435a9d337750fc82d', '0xfe2907dfa8db6e320cdbf45f0aa888f6135ec4f8' ] │ 20.558236588772328 │ [ '0x26d460c3Cf931Fb2014FA436a49e3Af08619810e' ] │
│ 2       │ '0xa8697b82a5e9f108296c6299859e82472340aea7-flare' │ 'WETH-flrETH'  │ 'sparkdex-v3.1' │ 'flare' │ 5790339.552560857  │ 0.08534560379111583  │ [ '0x1502fa4be69d526124d453619276faccab275d3d', '0x26a1fab310bd080542dc864647d05985360b16a5' ] │ 10.68909133888699  │ [ '0x26d460c3Cf931Fb2014FA436a49e3Af08619810e' ] │
│ 3       │ '0xc9baba3f36ccaa54675deecc327ec7eaa48cb97d-flare' │ 'sFLR-WFLR'    │ 'sparkdex-v3.1' │ 'flare' │ 3703467.3048712723 │ 0.0489874149995106   │ [ '0x12e605bc104e93b45e1ad99f9e555f659051c2bb', '0x1d80c49bbbcd1c0911346656b529df9e5c2f783d' ] │ 31.824329414076445 │ [ '0x26d460c3Cf931Fb2014FA436a49e3Af08619810e' ] │
│ 4       │ '0x724bd6413925dd4d513b35b1cf9c6f1c378e3691-flare' │ 'WETH-USD₮0'   │ 'sparkdex-v3.1' │ 'flare' │ 1691689.9313631523 │ 4.968327676458918    │ [ '0x1502fa4be69d526124d453619276faccab275d3d', '0xe7cd86e13ac4309349f30b3435a9d337750fc82d' ] │ 34.75006229085933  │ [ '0x26d460c3Cf931Fb2014FA436a49e3Af08619810e' ] │
│ 5       │ '0xf89c5a8465e8ce4ea3ad337b072a51ad5bdaf6e7-flare' │ 'WFLR-SPRK'    │ 'sparkdex-v3.1' │ 'flare' │ 1555781.8745606658 │ 0.5595370916876503   │ [ '0x1d80c49bbbcd1c0911346656b529df9e5c2f783d', '0x657097cc15fdec9e383db8628b57ea4a763f2ba0' ] │ 17.967897204807713 │ [ '0x26d460c3Cf931Fb2014FA436a49e3Af08619810e' ] │
│ 6       │ '0x63873f0d7165689022feef1b77428df357b33dcf-flare' │ 'WFLR-USD₮0'   │ 'sparkdex-v3.1' │ 'flare' │ 1345202.8069163857 │ 5.452690934753533    │ [ '0x1d80c49bbbcd1c0911346656b529df9e5c2f783d', '0xe7cd86e13ac4309349f30b3435a9d337750fc82d' ] │ 50.50476308768802  │ [ '0x26d460c3Cf931Fb2014FA436a49e3Af08619810e' ] │
│ 7       │ '0xe1d25fc5fd9a961cc924ea701d15c74571bfd6a9-flare' │ 'USDT-USD₮0'   │ 'sparkdex-v3.1' │ 'flare' │ 999834.039915557   │ 0.0014887230848432   │ [ '0x0b38e83b86d491735feaa0a791f65c2b99535396', '0xe7cd86e13ac4309349f30b3435a9d337750fc82d' ] │                    │                                                  │
│ 8       │ '0x3bc1ecbcd645e525508c570a0ff04480a5614a86-flare' │ 'WFLR-USDC.e'  │ 'sparkdex-v3.1' │ 'flare' │ 387645.22188530816 │ 13.029184756974907   │ [ '0x1d80c49bbbcd1c0911346656b529df9e5c2f783d', '0xfbda5f676cb37624f28265a144a48b0d6e87d3b6' ] │ 49.015573399269016 │ [ '0x26d460c3Cf931Fb2014FA436a49e3Af08619810e' ] │
│ 9       │ '0x67f246f1de19d4afc652dd85eb262a586cdbd82d-flare' │ 'WFLR-SPRK'    │ 'sparkdex-v3.1' │ 'flare' │ 336419.3608120514  │ 5.945693574391753    │ [ '0x1d80c49bbbcd1c0911346656b529df9e5c2f783d', '0x657097cc15fdec9e383db8628b57ea4a763f2ba0' ] │ 60.30146656816295  │ [ '0x26d460c3Cf931Fb2014FA436a49e3Af08619810e' ] │
└─────────┴────────────────────────────────────────────────────┴────────────────┴─────────────────┴─────────┴────────────────────┴──────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────────────────────────────────────┘
This adapter contains some pools with <10k TVL, these pools won't be shown in DefiLlama

@slasher125
Copy link
Collaborator

@0xNx pls split these into separate PRs, otherwise i cant' see the output here of each

@@ -20,15 +26,20 @@ const apy = async () => {
)
).data[0].data;

const chain = 'Flare';
Copy link
Collaborator

Choose a reason for hiding this comment

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

incorrect, we want to keep the capitalised version, no need to change this

Copy link
Contributor Author

@0xNx 0xNx Sep 2, 2025

Choose a reason for hiding this comment

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

image image

https://defillama.com/protocol/sparkdex

Any reason why SparkDEX v3.1 pools not displaying on the SparkDEX(Combined) Yield page, there are only v2 pools displaying.

Seems the chain name (flare vs Flare) is the reason ?

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.

3 participants