Update: Fix 0 volume tracking on Lunar Finance#7898
Conversation
Error in volume calculation
This file implements the LunarSweeperRouter functionality for on-chain volume tracking, including transaction parsing and volume calculation.
This file implements the Lunar Finance bridge aggregator, fetching and parsing bridge volume data from the Lunar analytics API.
This file implements a bridge aggregator for Lunar Finance, fetching and parsing daily bridge volume, fees, and revenue from the Lunar analytics API.
…lpers/lunarSweeperOnChain.ts
Refactor daily volume calculation to include API USD and on-chain sweeper router amounts.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
Summary by CodeRabbit
WalkthroughThis PR adds a shared Lunar Finance analytics helper module, then rewrites the DEX and bridge adapters to use it with multi-chain hourly adapter wiring, USD-wei parsing, supply-side revenue handling, and expanded methodology metadata. ChangesLunar Finance Adapter Refactor
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Adapter as Lunar adapter
participant Helper as helpers/lunarFinance.ts
participant API as Lunar API
Adapter->>Helper: fetchLunarAnalytics("dexs" / "bridge" / "sweeper", options)
Helper->>API: GET /api/analytics/{path}?startTimestamp&endTimestamp&chain
API-->>Helper: analytics envelope
Helper-->>Adapter: parsed envelope or throw
Adapter->>Helper: parseLunarUsdWei(field)
Adapter->>Helper: resolveLunarSupplySideRevenue(field, dailyFees, dailyRevenue)
Adapter-->>Adapter: return dailyVolume, dailyFees, dailyRevenue, dailyProtocolRevenue, dailyUserFees, dailySupplySideRevenue
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 12 | ❌ 3❌ Failed checks (3 warnings)
✅ Passed checks (12 passed)
✨ Finishing Touches✨ Simplify code
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. Comment |
|
The lunar-finance adapter exports: |
|
The lunar-finance-bridge adapter exports: |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 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 `@aggregators/lunar-finance/index.ts`:
- Around line 53-58: Avoid double-counting sweeper volume in the lunar-finance
aggregator by ensuring the protocol-wide API total is not added again on BSC
when `LUNAR_SWEEPER_ROUTER` already contributes on-chain sweeper volume. Update
the volume aggregation logic in `aggregators/lunar-finance/index.ts` around the
`parseLunarUsdWei`, `sweeperApiUsd`, and `dexUsd` assignments so the API-derived
sweeper amount is only applied once across chains, and make the same adjustment
in the related aggregation path referenced by the existing comment.
- Around line 60-70: The Lunar Finance adapter currently uses
`parseLunarUsdWei(...) || deriveLunarSupplySideRevenue(...)`, which treats an
explicit 0 as missing and skips validating supplied values. Update the
`dailySupplySideRevenue` logic in `aggregators/lunar-finance/index.ts` so it
derives only when `dexPayload.dailySupplySideRevenue` is absent, and otherwise
parses the supplied value and validates that `Fees = Revenue +
SupplySideRevenue` within a small tolerance using the existing `dailyFees`,
`dailyRevenue`, and `deriveLunarSupplySideRevenue` flow.
- Around line 45-48: The lunar finance aggregator is swallowing recoverable
sweeper API errors by using an empty fallback and Promise.all in the same flow.
Update the logic in the lunar-finance index entry to fetch the required DEX
payload first via fetchLunarAnalytics("dexs", options), then call the optional
sweeper fetch separately with a logged catch that records the failure before
returning the fallback. Keep the sweeper fallback only for the optional path,
and remove Promise.all so errors are not silently hidden.
In `@bridge-aggregators/lunar-finance-bridge/index.ts`:
- Around line 37-47: The Lunar Finance bridge fee parsing currently uses a falsy
fallback in the `dailySupplySideRevenue` assignment, which treats an explicit 0
as missing and skips validation of supplied values. Update `parseLunarUsdWei`,
`deriveLunarSupplySideRevenue`, and the `dailySupplySideRevenue` handling in the
bridge logic so that derivation happens only when the provider omits the field,
not when it is zero. When the API supplies a value, validate that `dailyRevenue
+ dailySupplySideRevenue === dailyFees` for the period and only derive as a
fallback if the field is absent.
In `@helpers/lunarFinance.ts`:
- Around line 140-146: The parseLunarUsdWei helper is silently coercing
malformed Lunar USD input to zero, which hides bad upstream data. Update
parseLunarUsdWei to keep returning 0 only when BalanceField.usd is absent, but
validate the raw string/number strictly and throw an error for malformed,
partial, non-finite, or negative values instead of falling back to 0. Use the
existing parseLunarUsdWei function and BalanceField shape to locate the fix, and
ensure callers see the failure rather than silently underreporting values.
In `@helpers/lunarSweeperOnChain.ts`:
- Around line 1-82: The LunarSweeperRouter logic in fetchSweeperOnChainVolume
and LUNAR_SWEEPER_ROUTER is adapter-specific and should not live in a shared
helper unless it is reused by multiple adapters. Move this code under
aggregators/lunar-finance/ (or equivalent Lunar adapter code) and keep helpers
only for reusable logic, or refactor the router address/chain start data into
parameters so the helper is generic for 2+ adapters.
- Around line 30-47: Separate selector filtering from decoding in decodeLegs:
keep returning [] when ROUTER_IFACE.parseTransaction identifies a non-sweep
selector, but do not swallow parseTransaction errors for sweep and
sweepWithPermit2 calls. Update decodeLegs so malformed router calldata for those
known selectors is rethrown instead of caught and treated as empty, while
preserving the current empty-array behavior for missing/too-short data and
unknown methods.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 84552518-7cf2-41d3-a9a2-40c30bfd246e
📒 Files selected for processing (4)
aggregators/lunar-finance/index.tsbridge-aggregators/lunar-finance-bridge/index.tshelpers/lunarFinance.tshelpers/lunarSweeperOnChain.ts
…chain only; API fallback only if on-chain fails
|
The lunar-finance adapter exports: |
|
@cardmagic @FelixBruguera Is this PR eligible for merging? If yes when will it be assined and merged |
bheluga
left a comment
There was a problem hiding this comment.
@Enniwealth thanks for the PR.
Any reason why you have mentioned so many chains if you are using only ethereum?
Lunar Finance is a Dex aggregator and we integrate providers such as (Squid, Jupiter, Near Intents, Relay etc) that support multiple chains both evm and non evm. We are not only on ethereum. You can verify here -> |
I mean according to your code, LUNAR_PRIMARY_CHAIN is ethereum, and onchain sweeper has data only for bsc, so for all other chains, we simply return 0, so whats the point of having all those chains? |
That's a bug. My apologies i will fix this in the next commit. Give me a few minutes |
|
The lunar-finance adapter exports: |
|
The lunar-finance-bridge adapter exports: |
Fixed. Thanks for the feedback |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
helpers/lunarFinance.ts (1)
178-190: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Number.parseFloatstill allows malformed trailing garbage through undetected.The past-review fix added throw-on-
NaN/negative, butNumber.parseFloatitself accepts partial numeric strings (e.g."123abc"→123), so a malformed upstream value would still be silently truncated to a plausible-looking number instead of throwing, which is exactly the failure mode the earlier review comment ("never swallow errors silently") was meant to close. Use strictNumber(...)(which returnsNaNfor any trailing non-numeric characters) instead ofNumber.parseFloat.🐛 Proposed fix
- const n = Number.parseFloat(raw); + const n = Number(raw);🤖 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 `@helpers/lunarFinance.ts` around lines 178 - 190, The strict parsing in parseLunarUsdWei still accepts malformed numeric strings because Number.parseFloat can truncate trailing garbage, so update the parsing logic to use Number(...) instead of Number.parseFloat. Keep the existing hasLunarUsdField, empty/zero checks, and finite/negative validation in parseLunarUsdWei so any non-numeric or partially numeric usd value throws instead of being silently coerced.Source: Coding guidelines
bridge-aggregators/lunar-finance-bridge/index.ts (1)
75-88: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSame simplification opportunity as the DEX aggregator — collapse to
chains+ singlestart.
fetchandstartare identical for every chain in the generatedadaptermap here too. As per coding guidelines, "Choose the simplest adapter shape that fits: usechainsplus a singlestartwhen all chains share the same start."♻️ Proposed simplification
-const adapter: SimpleAdapter = { - version: 2, - pullHourly: true, - adapter: Object.fromEntries( - LUNAR_ADAPTER_CHAINS.map((chain) => [ - chain, - { fetch, start: LUNAR_DEFAULT_START }, - ]), - ), +const adapter: SimpleAdapter = { + version: 2, + pullHourly: true, + fetch, + chains: LUNAR_ADAPTER_CHAINS, + start: LUNAR_DEFAULT_START, methodology, breakdownMethodology, };🤖 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 `@bridge-aggregators/lunar-finance-bridge/index.ts` around lines 75 - 88, The adapter in the Lunar Finance bridge is unnecessarily expanding identical per-chain entries in the SimpleAdapter map. Simplify the `adapter` object by using the `chains` field with a single shared `start` value instead of building entries with `Object.fromEntries`; keep the existing `fetch`, `methodology`, and `breakdownMethodology` wiring, and update the `adapter` definition accordingly so the shape matches the simplest form used when all chains share the same start.Source: Coding guidelines
aggregators/lunar-finance/index.ts (1)
116-129: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSimplify the per-chain adapter map —
fetch/startare identical for every chain.Every entry in
Object.fromEntries(LUNAR_ADAPTER_CHAINS.map(...))maps to the exact same{ fetch, start: LUNAR_DEFAULT_START }. Per the repo's adapter-shape guideline, when all chains share the samestartand there's no per-chain config, preferchains: [...] + startover a synthesized per-chain object — it's simpler and avoids future drift between the chain list and the generated map.♻️ Proposed simplification
-const adapter: SimpleAdapter = { - version: 2, - pullHourly: true, - adapter: Object.fromEntries( - LUNAR_ADAPTER_CHAINS.map((chain) => [ - chain, - { fetch, start: LUNAR_DEFAULT_START }, - ]), - ), +const adapter: SimpleAdapter = { + version: 2, + pullHourly: true, + fetch, + chains: LUNAR_ADAPTER_CHAINS, + start: LUNAR_DEFAULT_START, methodology, breakdownMethodology, };🤖 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 `@aggregators/lunar-finance/index.ts` around lines 116 - 129, The adapter in lunar-finance is building an unnecessary per-chain map with Object.fromEntries over LUNAR_ADAPTER_CHAINS even though every chain uses the same fetch and LUNAR_DEFAULT_START. Simplify the adapter definition by switching the SimpleAdapter configuration to the shared chains/start pattern instead of generating identical entries, and keep methodology/breakdownMethodology unchanged; use the existing LUNAR_ADAPTER_CHAINS and LUNAR_DEFAULT_START symbols to locate the adapter object.Source: Coding guidelines
🤖 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 `@aggregators/lunar-finance/index.ts`:
- Around line 44-72: The sweeper block in lunar-finance/index.ts is catching
both fetch failures and revenue reconciliation errors in the same handler, which
hides genuine data-integrity issues. Narrow the try/catch around
fetchLunarAnalytics("sweeper", options) so only endpoint/network failures are
downgraded to the unavailable warning, and let resolveLunarSupplySideRevenue
validation mismatches propagate or be logged separately at a higher severity.
Keep the existing aggregation logic for sweeper fees, revenue, and supply-side
revenue, but distinguish the fetch path from the reconciliation path.
---
Outside diff comments:
In `@aggregators/lunar-finance/index.ts`:
- Around line 116-129: The adapter in lunar-finance is building an unnecessary
per-chain map with Object.fromEntries over LUNAR_ADAPTER_CHAINS even though
every chain uses the same fetch and LUNAR_DEFAULT_START. Simplify the adapter
definition by switching the SimpleAdapter configuration to the shared
chains/start pattern instead of generating identical entries, and keep
methodology/breakdownMethodology unchanged; use the existing
LUNAR_ADAPTER_CHAINS and LUNAR_DEFAULT_START symbols to locate the adapter
object.
In `@bridge-aggregators/lunar-finance-bridge/index.ts`:
- Around line 75-88: The adapter in the Lunar Finance bridge is unnecessarily
expanding identical per-chain entries in the SimpleAdapter map. Simplify the
`adapter` object by using the `chains` field with a single shared `start` value
instead of building entries with `Object.fromEntries`; keep the existing
`fetch`, `methodology`, and `breakdownMethodology` wiring, and update the
`adapter` definition accordingly so the shape matches the simplest form used
when all chains share the same start.
In `@helpers/lunarFinance.ts`:
- Around line 178-190: The strict parsing in parseLunarUsdWei still accepts
malformed numeric strings because Number.parseFloat can truncate trailing
garbage, so update the parsing logic to use Number(...) instead of
Number.parseFloat. Keep the existing hasLunarUsdField, empty/zero checks, and
finite/negative validation in parseLunarUsdWei so any non-numeric or partially
numeric usd value throws instead of being silently coerced.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 51d5af92-a505-4a96-b5a0-6ed7466b1395
📒 Files selected for processing (3)
aggregators/lunar-finance/index.tsbridge-aggregators/lunar-finance-bridge/index.tshelpers/lunarFinance.ts
|
The lunar-finance adapter exports: |
|
The lunar-finance-bridge adapter exports: |
Narrow the sweeper try/catch to wrap only the analytics fetch
|
The lunar-finance adapter exports: |
|
The lunar-finance-bridge adapter exports: |
Enniwealth
left a comment
There was a problem hiding this comment.
I have fixed everything needed
@bheluga I have made changes to the issue you spotted. Just following up to know if there is something i am missing for the PR to get merged |
|
@Enniwealth aggregators data looks wrong |
|
@bheluga It has been fixed. Can you please try again?
|
|
@Enniwealth thanks for the PR |


Summary
Adds and hardens Lunar Finance dimension adapters for DefiLlama:
aggregators/lunar-finance— DEX aggregator volume, fees, and revenue (meta-aggregator swaps + batch sweeper)bridge-aggregators/lunar-finance-bridge— Bridge aggregator volume and fee dimensionsBoth adapters use Lunar’s public analytics API (
lunar-backend-production.up.railway.app) with disclosed methodology. BSC sweeper volume is supplemented on-chain viaLunarSweeperRouterwhere deployed.Official site: https://lunarfinance.io
Data sources
/api/analytics/dexs/api/analytics/sweeperLunarSweeperRouteron BSCsweep/sweepWithPermit2tx inputs/api/analytics/bridgeKey design decisions
Protocol-wide API totals (no double-counting)
Verified that the Lunar analytics API currently returns the same protocol-wide totals for every
chainquery param. To avoid inflating volume/fees (~50×–70×), API metrics are attributed onethereumonly (LUNAR_PRIMARY_CHAIN). Other registered chains return zero for API-derived dimensions until per-chain filtering is available.BSC sweeper (no double-counting)
On BSC, sweeper volume comes from on-chain router balances only — not from both API sweeper USD and on-chain token amounts. On indexer failure (e.g. CI), the adapter logs a warning and continues without crashing.
Chain coverage (~50 chains)
Adapters register ~50 supported chains derived from the Lunar chain-ID mapping, excluding dead/niche chains (e.g.
kroma,canto,okexchain) that are not supported in-app and cause unreliable RPC lookups in tests. FullLUNAR_CHAIN_IDmapping is retained for API queries.Fee accounting (
Fees = Revenue + SupplySideRevenue)Both adapters return
dailySupplySideRevenue, parsed from the API when available or derived asdailyFees - dailyRevenue. IfdailyRevenue > dailyFees, the adapter throws instead of clamping to zero, so upstream data issues are surfaced rather than masked.Files changed
helpers/lunarFinance.tshelpers/lunarSweeperOnChain.tsaggregators/lunar-finance/index.tsversion: 2,pullHourly: true)bridge-aggregators/lunar-finance-bridge/index.tsAdapter metadata
version: 2pullHourly: truemethodology+breakdownMethodologyon both adaptersdailySupplySideRevenueon DEX and bridge adaptersTest plan
pnpm run ts-checkpnpm test aggregators lunar-financepnpm test bridge-aggregators lunar-finance-bridgeethereumonly