Skip to content

Add tag breakdown to perp dexes - #7801

Open
FelixBruguera wants to merge 9 commits into
DefiLlama:masterfrom
FelixBruguera:category-breakdown
Open

Add tag breakdown to perp dexes#7801
FelixBruguera wants to merge 9 commits into
DefiLlama:masterfrom
FelixBruguera:category-breakdown

Conversation

@FelixBruguera

Copy link
Copy Markdown
Contributor

https://github.com/DefiLlama/internal-docs/issues/40
Added breakdownByTag to the runner to return a breakdown of perp volume by asset tag (RWA, Layer 1, Meme...) and refactored multiple runAtCurrTime perp dex adapters to return balance objects with symbols

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • New Features
    • Added optional tag-based aggregation so adapter outputs can include a per-tag USD breakdown.
  • Refactor
    • Updated multiple DEX volume adapters to compute daily volume as a per-asset USD balances breakdown (instead of a single aggregated number).
    • Improved volume calculation flows in affected adapters (including using shared balance/valuation utilities, incremental accumulation, and consistent scaling).

Walkthrough

Six DEX adapters (apollox, bluefin-pro, citrex-markets, dydx-v4, jupiter-perpetual, variational-omni, vest) are refactored to compute dailyVolume as per-asset Balances objects via createBalances()/addUSDValue instead of numeric sums. Concurrently, runAdapter gains an optional getTag callback that buckets per-token USD values into a new breakdownByTag field in the returned record.

Changes

Per-asset volume and tag-breakdown aggregation

Layer / File(s) Summary
runAdapter: getTag option and breakdownByTag aggregation
adapters/utils/runAdapter.ts
AdapterRunOptions gains optional getTag; _runAdapter initializes a breakdownByTag accumulator, populates it per-token during Balances processing by mapping symbols through getTag, nullifies it when empty, and includes it in the returned adaptorRecordV2JSON.
DEX adapters: createBalances-based dailyVolume
dexs/apollox/index.ts, dexs/bluefin-pro/index.ts, dexs/citrex-markets/index.ts, dexs/dydx-v4/index.ts, dexs/jupiter-perpetual/index.ts, dexs/variational-omni/index.ts, dexs/vest/index.ts
All seven adapters replace numeric reduce/sum dailyVolume with options.createBalances() + addUSDValue keyed by base asset symbol. apollox additionally merges v1/v2 via addBalances and gates on getUSDValue(). variational-omni adds a baseAsset() helper for ticker normalization. jupiter-perpetual switches from mint-keyed to symbol-keyed parallel market fetches.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

methodology

Suggested reviewers

  • treeoflife2
🚥 Pre-merge checks | ✅ 8 | ❌ 7

❌ Failed checks (7 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title does not follow the specified format '[type] protocol-name - description' and is vague about what changes were made. Revise title to follow format: e.g., '[feat] perp dexes - add tag breakdown to runner' or similar, specifying the type and making the scope clearer.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 50.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Version 2 Required ⚠️ Warning citrex-markets/index.ts remains at version: 1 after refactoring. Three adapters (apollox, bluefin-pro, dydx-v4) lack explicit version fields. Adapters being refactored to use balance objects should... Upgrade citrex-markets to version: 2 and add explicit version: 2 fields to apollox, bluefin-pro, and dydx-v4 adapters.
Pullhourly Required For Version 2 ⚠️ Warning Three version 2 adapters are missing the required pullHourly key: jupiter-perpetual, variational-omni, and vest. Per check requirements, all v2 adapters must explicitly set it. Add pullHourly: true, to the adapter config objects in jupiter-perpetual/index.ts (line 54-55), variational-omni/index.ts (line 31-32), and vest/index.ts (line 29-30).
Adapter Shape ⚠️ Warning Two adapters violate adapter shape guidelines: bluefin-pro and vest use per-chain adapter objects when they should use simple chains array format for single-chain adapters. Refactor bluefin-pro and vest adapters from nested per-chain object to simple shape: { fetch, chains: [CHAIN], start, runAtCurrTime, ... }
Efficiency And Error Handling ⚠️ Warning Multiple efficiency and error handling violations: (1) dexs/variational-omni/index.ts lacks Number validation for NaN/null; (2) dexs/bluefin-pro/index.ts magic number 1e9 has no source comment; (3)... Add validation (Number.isFinite, null checks) to variational-omni line 20; add explanatory comment for 1e9 divisor in bluefin-pro; refactor jupiter-perpetual to use batched API calls instead of individual httpGet in Promise.all.
Methodology Keys ⚠️ Warning The breakdownByTag structure in runAdapter uses code field names (dailyVolume, dailyFees) as keys instead of display names (Volume, Fees) as required by the check. Convert breakdownByTag keys from code field names to display names: map dailyVolume→Volume, dailyFees→Fees, dailyRevenue→Revenue, etc.
✅ Passed checks (8 passed)
Check name Status Explanation
Description check ✅ Passed The PR description contains a relevant summary but does not follow the provided template structure, as this is not a new protocol listing.
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.
Breakdown Methodology Check ✅ Passed Check is not applicable: PR modifies perpetual DEX adapters only, not fees adapters; no .add() calls or breakdownMethodology usage found in changed files.
Income Statement Compliance ✅ Passed This PR contains only perpetual DEX adapters (returning dailyVolume/openInterestAtEnd), not fees adapters. The Income Statement Compliance check applies only to fees adapters and is not applicable...
Dune Adapters Are Version 1 ✅ Passed No adapters in this PR use Dune queries (queryDune, queryDuneSql). The check requiring Dune adapters to export version 1 is not applicable.
Income Statement Balance ✅ Passed PR modifies only perpetual/volume DEX adapters returning dailyVolume/openInterestAtEnd, not fees adapters; Income Statement Balance check is inapplicable.
Fetchoptions Usage ✅ Passed All modified adapters correctly accept a single FetchOptions argument, use options.createBalances() properly, contain no old 3-argument signatures, no active time recomputation, no unused arguments...

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

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

The apollox adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs apollox

🦙 Running APOLLOX adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 00:00:00 GMT
End Date:	Tue, 23 Jun 2026 00:00:00 GMT
---------------------------------------------------

OFF_CHAIN 👇
Backfill start time: 21/4/2023
Daily volume: 1.83 B




FEES BREAKDOWN 👇

@github-actions

Copy link
Copy Markdown

The bluefin-pro adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs bluefin-pro

🦙 Running BLUEFIN-PRO adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 00:00:00 GMT
End Date:	Tue, 23 Jun 2026 00:00:00 GMT
---------------------------------------------------

SUI 👇
Daily volume: 2.08 M
Open interest at end: 1.59 M




FEES BREAKDOWN 👇

@github-actions

Copy link
Copy Markdown

The citrex-markets adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs citrex-markets

🦙 Running CITREX-MARKETS adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 00:00:00 GMT
End Date:	Tue, 23 Jun 2026 00:00:00 GMT
---------------------------------------------------

error fetching block [Error: Llama RPC error! method: getBlock 
- host: https://sei.drpc.org error: Request failed with status code 500
- host: https://evm-rpc.sei-apis.com error: requested height 150023881 has been pruned; earliest available is 212259999
- host: https://sei.api.pocket.network error: requested height 150023881 has been pruned; earliest available is 215522112] {
  _underlyingError: '[object Object]',
  _isCustomError: true
}
error fetching block [Error: Llama RPC error! method: getBlock 
- host: https://sei.drpc.org error: Request failed with status code 500
- host: https://evm-rpc.sei-apis.com error: requested height 150023881 has been pruned; earliest available is 212259999
- host: https://sei.api.pocket.network error: requested height 150023881 has been pruned; earliest available is 211067197] {
  _underlyingError: '[object Object]',
  _isCustomError: true
}
SEI 👇
Backfill start time: 18/2/2025
Daily volume: 16.25 M
Open interest at end: 7.96 M




FEES BREAKDOWN 👇

@github-actions

Copy link
Copy Markdown

The dydx-v4 adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs dydx-v4

🦙 Running DYDX-V4 adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 00:00:00 GMT
End Date:	Tue, 23 Jun 2026 00:00:00 GMT
---------------------------------------------------

DYDX 👇
Backfill start time: 26/10/2023
Daily volume: 124.04 M
Open interest at end: 69.56 M




FEES BREAKDOWN 👇

@github-actions

Copy link
Copy Markdown

The jupiter-perpetual adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs jupiter-perpetual

🦙 Running JUPITER-PERPETUAL adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 13:08:20 GMT
End Date:	Tue, 23 Jun 2026 13:08:20 GMT
---------------------------------------------------

SOLANA 👇
Backfill start time: 23/1/2024
Daily volume: 275.92 M
End timestamp: 1782220099 (2026-06-23T13:08:19.000Z)




FEES BREAKDOWN 👇

@github-actions

Copy link
Copy Markdown

The variational-omni adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs variational-omni

🦙 Running VARIATIONAL-OMNI adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 13:08:24 GMT
End Date:	Tue, 23 Jun 2026 13:08:24 GMT
---------------------------------------------------

ARBITRUM 👇
Backfill start time: 30/1/2025
Open interest at end: 1.04 B
Daily volume: 761.94 M
End timestamp: 1782220103 (2026-06-23T13:08:23.000Z)




FEES BREAKDOWN 👇

@github-actions

Copy link
Copy Markdown

The vest adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs vest

🦙 Running VEST adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 13:08:29 GMT
End Date:	Tue, 23 Jun 2026 13:08:29 GMT
---------------------------------------------------

OFF_CHAIN 👇
Backfill start time: 1/1/2025
Daily volume: 50.56 M
End timestamp: 1782220108 (2026-06-23T13:08:28.000Z)




FEES BREAKDOWN 👇

@coderabbitai coderabbitai Bot added the dexs label Jun 23, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 `@dexs/jupiter-perpetual/index.ts`:
- Around line 29-34: The code uses Promise.all to execute all market HTTP
requests concurrently without bounds, which violates the repository's coding
guidelines. Replace the Promise.all(markets.map(...)) pattern in the dailyVolume
block with PromisePool to limit concurrency. Keep the same async function logic
that calls httpGet for each market with mint and symbol parameters and
accumulates volume results via dailyVolume.addUSDValue, but use PromisePool
instead to prevent unbounded fan-out as the markets list grows.

In `@dexs/variational-omni/index.ts`:
- Around line 16-18: The code currently uses a nullish coalescing operator on
data.listings which silently defaults to an empty array when the listings
payload is missing, resulting in incorrect zero volume being written. Remove the
`?? []` fallback pattern in the loop that iterates over data.listings and
instead add validation logic before the loop that checks if data.listings exists
and is a valid array; throw an error with a descriptive message if validation
fails, ensuring that missing or invalid adapter responses fail loudly rather
than being swallowed silently.

In `@dexs/vest/index.ts`:
- Around line 16-19: The code currently coerces missing ticker.quoteVolume
values to zero using Number(ticker.quoteVolume || 0), which hides missing API
fields and underreports volume. Instead of using the fallback to zero, add
validation to check that ticker.quoteVolume exists and is a valid number, and
throw an error if it's absent or non-numeric. This ensures data integrity by
marking the day unavailable rather than silently charting with incorrect volume
data in the loop where dailyVolume.addUSDValue is called.
🪄 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: 02b6f1f6-5e62-46f0-8bbe-b765a2bdf6a8

📥 Commits

Reviewing files that changed from the base of the PR and between 853b15b and 0afea91.

📒 Files selected for processing (8)
  • adapters/utils/runAdapter.ts
  • dexs/apollox/index.ts
  • dexs/bluefin-pro/index.ts
  • dexs/citrex-markets/index.ts
  • dexs/dydx-v4/index.ts
  • dexs/jupiter-perpetual/index.ts
  • dexs/variational-omni/index.ts
  • dexs/vest/index.ts

Comment on lines +29 to +34
const dailyVolume = options.createBalances();
await Promise.all(markets.map(async ({ mint, symbol }) => {
const res: any[] = (await httpGet(url(mint), { headers: header_user })).flat();
const volume = res.reduce((acc: number, { result }: any) => acc + result.data.json.volume, 0);
dailyVolume.addUSDValue(volume, { id: symbol, isUSDValue: true });
}));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Use PromisePool for the per-market HTTP fan-out.

Line 30 starts all non-EVM market requests with Promise.all; use the repo’s PromisePool pattern instead so this does not become unbounded if the market list grows. As per coding guidelines, “Use PromisePool for non-EVM calls” and “avoid Promise.all.”

🤖 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 `@dexs/jupiter-perpetual/index.ts` around lines 29 - 34, The code uses
Promise.all to execute all market HTTP requests concurrently without bounds,
which violates the repository's coding guidelines. Replace the
Promise.all(markets.map(...)) pattern in the dailyVolume block with PromisePool
to limit concurrency. Keep the same async function logic that calls httpGet for
each market with mint and symbol parameters and accumulates volume results via
dailyVolume.addUSDValue, but use PromisePool instead to prevent unbounded
fan-out as the markets list grows.

Source: Coding guidelines

Comment thread dexs/variational-omni/index.ts Outdated
Comment thread dexs/vest/index.ts
Comment on lines +16 to +19
for (const ticker of data) {
if (blacklisted_tickers.includes(ticker.symbol)) continue;
const baseAsset = String(ticker.symbol).split("-")[0]; // "TSM-USD-PERP" -> "TSM", "BZ-PERP" -> "BZ"
dailyVolume.addUSDValue(Number(ticker.quoteVolume || 0), { id: baseAsset, isUSDValue: true });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not coerce missing ticker volume to zero.

Number(ticker.quoteVolume || 0) hides missing API fields and underreports volume instead of failing the run. Throw on absent/non-numeric quoteVolume so the day is marked unavailable rather than charted incorrectly.

Proposed fix
     for (const ticker of data) {
         if (blacklisted_tickers.includes(ticker.symbol)) continue;
         const baseAsset = String(ticker.symbol).split("-")[0]; // "TSM-USD-PERP" -> "TSM", "BZ-PERP" -> "BZ"
-        dailyVolume.addUSDValue(Number(ticker.quoteVolume || 0), { id: baseAsset, isUSDValue: true });
+        if (ticker.quoteVolume == null) throw new Error(`Vest ticker missing quoteVolume for ${ticker.symbol}`);
+        const quoteVolume = Number(ticker.quoteVolume);
+        if (!Number.isFinite(quoteVolume)) throw new Error(`Invalid Vest quoteVolume for ${ticker.symbol}`);
+        dailyVolume.addUSDValue(quoteVolume, { id: baseAsset, isUSDValue: true });
     }

Based on learnings, adapter fetches should not return sentinel zero values for missing data; as per coding guidelines, never swallow errors silently.

📝 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
for (const ticker of data) {
if (blacklisted_tickers.includes(ticker.symbol)) continue;
const baseAsset = String(ticker.symbol).split("-")[0]; // "TSM-USD-PERP" -> "TSM", "BZ-PERP" -> "BZ"
dailyVolume.addUSDValue(Number(ticker.quoteVolume || 0), { id: baseAsset, isUSDValue: true });
for (const ticker of data) {
if (blacklisted_tickers.includes(ticker.symbol)) continue;
const baseAsset = String(ticker.symbol).split("-")[0]; // "TSM-USD-PERP" -> "TSM", "BZ-PERP" -> "BZ"
if (ticker.quoteVolume == null) throw new Error(`Vest ticker missing quoteVolume for ${ticker.symbol}`);
const quoteVolume = Number(ticker.quoteVolume);
if (!Number.isFinite(quoteVolume)) throw new Error(`Invalid Vest quoteVolume for ${ticker.symbol}`);
dailyVolume.addUSDValue(quoteVolume, { id: baseAsset, isUSDValue: true });
}
🤖 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 `@dexs/vest/index.ts` around lines 16 - 19, The code currently coerces missing
ticker.quoteVolume values to zero using Number(ticker.quoteVolume || 0), which
hides missing API fields and underreports volume. Instead of using the fallback
to zero, add validation to check that ticker.quoteVolume exists and is a valid
number, and throw an error if it's absent or non-numeric. This ensures data
integrity by marking the day unavailable rather than silently charting with
incorrect volume data in the loop where dailyVolume.addUSDValue is called.

Sources: Coding guidelines, Learnings

@github-actions

Copy link
Copy Markdown

The apollox adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs apollox

🦙 Running APOLLOX adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 00:00:00 GMT
End Date:	Tue, 23 Jun 2026 00:00:00 GMT
---------------------------------------------------

OFF_CHAIN 👇
Backfill start time: 21/4/2023
Daily volume: 1.79 B




FEES BREAKDOWN 👇

@github-actions

Copy link
Copy Markdown

The bluefin-pro adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs bluefin-pro

🦙 Running BLUEFIN-PRO adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 00:00:00 GMT
End Date:	Tue, 23 Jun 2026 00:00:00 GMT
---------------------------------------------------

SUI 👇
Daily volume: 2.08 M
Open interest at end: 1.53 M




FEES BREAKDOWN 👇

@github-actions

Copy link
Copy Markdown

The citrex-markets adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs citrex-markets

🦙 Running CITREX-MARKETS adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 00:00:00 GMT
End Date:	Tue, 23 Jun 2026 00:00:00 GMT
---------------------------------------------------

error fetching block [Error: Llama RPC error! method: getBlock 
- host: https://sei.api.pocket.network error: requested height 150023881 has been pruned; earliest available is 209569999
- host: https://evm-rpc.sei-apis.com error: requested height 150023881 has been pruned; earliest available is 212259999] {
  _underlyingError: '[object Object]',
  _isCustomError: true
}
error fetching block [Error: Llama RPC error! method: getBlock 
- host: https://sei.api.pocket.network error: requested height 150023881 has been pruned; earliest available is 215544026
- host: https://evm-rpc.sei-apis.com error: requested height 150023881 has been pruned; earliest available is 212259999] {
  _underlyingError: '[object Object]',
  _isCustomError: true
}
SEI 👇
Backfill start time: 18/2/2025
Daily volume: 15.75 M
Open interest at end: 7.98 M




FEES BREAKDOWN 👇

@github-actions

Copy link
Copy Markdown

The dydx-v4 adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs dydx-v4

🦙 Running DYDX-V4 adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 00:00:00 GMT
End Date:	Tue, 23 Jun 2026 00:00:00 GMT
---------------------------------------------------

DYDX 👇
Backfill start time: 26/10/2023
Daily volume: 113.85 M
Open interest at end: 69.64 M




FEES BREAKDOWN 👇

@github-actions

Copy link
Copy Markdown

The jupiter-perpetual adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs jupiter-perpetual

🦙 Running JUPITER-PERPETUAL adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 15:39:19 GMT
End Date:	Tue, 23 Jun 2026 15:39:19 GMT
---------------------------------------------------

SOLANA 👇
Backfill start time: 23/1/2024
Daily volume: 274.19 M
End timestamp: 1782229158 (2026-06-23T15:39:18.000Z)




FEES BREAKDOWN 👇

@github-actions

Copy link
Copy Markdown

The variational-omni adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs variational-omni

🦙 Running VARIATIONAL-OMNI adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 15:39:21 GMT
End Date:	Tue, 23 Jun 2026 15:39:21 GMT
---------------------------------------------------

ARBITRUM 👇
Backfill start time: 30/1/2025
Open interest at end: 1.04 B
Daily volume: 732.89 M
End timestamp: 1782229160 (2026-06-23T15:39:20.000Z)




FEES BREAKDOWN 👇

@github-actions

Copy link
Copy Markdown

The vest adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts dexs vest

🦙 Running VEST adapter 🦙
---------------------------------------------------
Start Date:	Mon, 22 Jun 2026 15:39:26 GMT
End Date:	Tue, 23 Jun 2026 15:39:26 GMT
---------------------------------------------------

OFF_CHAIN 👇
Backfill start time: 1/1/2025
Daily volume: 48.82 M
End timestamp: 1782229165 (2026-06-23T15:39:25.000Z)




FEES BREAKDOWN 👇

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@dexs/variational-omni/index.ts`:
- Around line 19-21: In the for loop iterating through data.listings, the
conversion of listing.volume_24h using Number() does not validate the result
before adding to dailyVolume. After converting listing.volume_24h to a Number,
validate that the result is finite using Number.isFinite() to ensure it is not
NaN or Infinity. If the value is not finite, throw an error or skip the entry
loudly to fail fast rather than silently accepting malformed data that would
corrupt the dailyVolume output.
🪄 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: 3684db5b-1f3d-4b3e-86f9-ec0da8f8777a

📥 Commits

Reviewing files that changed from the base of the PR and between 0afea91 and 137fcec.

📒 Files selected for processing (1)
  • dexs/variational-omni/index.ts

Comment on lines +19 to +21
for (const listing of data.listings) {
dailyVolume.addUSDValue(Number(listing.volume_24h), { id: baseAsset(String(listing.ticker)), isUSDValue: true });
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Validate each listing’s volume_24h before adding to dailyVolume.

Line 20 converts listing.volume_24h with Number(...) but does not verify finiteness. A malformed row (null, missing, or non-numeric) can produce NaN and pollute persisted volume output.

Proposed fix
   for (const listing of data.listings) {
-    dailyVolume.addUSDValue(Number(listing.volume_24h), { id: baseAsset(String(listing.ticker)), isUSDValue: true });
+    if (listing.volume_24h == null) {
+      throw new Error(`Variational listing missing volume_24h for ${listing.ticker}`)
+    }
+    const volume24h = Number(listing.volume_24h)
+    if (!Number.isFinite(volume24h)) {
+      throw new Error(`Invalid Variational volume_24h for ${listing.ticker}`)
+    }
+    dailyVolume.addUSDValue(volume24h, { id: baseAsset(String(listing.ticker)), isUSDValue: true });
   }

Based on learnings, adapter payload gaps should fail loudly rather than emitting wrong chart data; as per coding guidelines, avoid silently accepting bad data.

📝 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
for (const listing of data.listings) {
dailyVolume.addUSDValue(Number(listing.volume_24h), { id: baseAsset(String(listing.ticker)), isUSDValue: true });
}
for (const listing of data.listings) {
if (listing.volume_24h == null) {
throw new Error(`Variational listing missing volume_24h for ${listing.ticker}`)
}
const volume24h = Number(listing.volume_24h)
if (!Number.isFinite(volume24h)) {
throw new Error(`Invalid Variational volume_24h for ${listing.ticker}`)
}
dailyVolume.addUSDValue(volume24h, { id: baseAsset(String(listing.ticker)), isUSDValue: true });
}
🤖 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 `@dexs/variational-omni/index.ts` around lines 19 - 21, In the for loop
iterating through data.listings, the conversion of listing.volume_24h using
Number() does not validate the result before adding to dailyVolume. After
converting listing.volume_24h to a Number, validate that the result is finite
using Number.isFinite() to ensure it is not NaN or Infinity. If the value is not
finite, throw an error or skip the entry loudly to fail fast rather than
silently accepting malformed data that would corrupt the dailyVolume output.

Sources: Coding guidelines, Learnings

@g1nt0ki
g1nt0ki requested a review from noateden June 23, 2026 20:54
@noateden noateden self-assigned this Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants