addition of supernova-amm adaptor#2416
Conversation
📝 WalkthroughWalkthroughAdds a Supernova AMM adaptor that fetches pool TVL and volumes from a subgraph, queries on-chain gauge and factory contracts for reward data, and combines prices to compute APY for pools. Changes
Sequence DiagramsequenceDiagram
actor Client
participant Adaptor as "Adaptor\n(index.js)"
participant Subgraph as "Subgraph\n(Volumes/TVL)"
participant Factory as "Factory\n(allPairs)"
participant Voter as "Voter\n(gauges)"
participant Gauge as "Gauge\n(rewardRate/totalSupply)"
participant Prices as "Price Service\n(CoinGecko/Subgraph)"
participant Calc as "APY Calculator"
Client->>Adaptor: apy(timestamp)
Adaptor->>Subgraph: query pools, TVL, volumes
Subgraph-->>Adaptor: pool list + metrics
Adaptor->>Factory: allPairsLength / allPairs(i)
Factory-->>Adaptor: pool addresses
Adaptor->>Voter: gauges(poolAddress)
Voter-->>Adaptor: gaugeAddress
Adaptor->>Gauge: rewardRate(), totalSupply(), poolSupply
Gauge-->>Adaptor: reward metrics
Adaptor->>Prices: fetch token prices
Prices-->>Adaptor: price data
Adaptor->>Calc: combine TVL, rewards, prices
Calc-->>Adaptor: APY per pool
Adaptor-->>Client: pools with TVL, volumes, APY
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
supernova-amm/index.js (1)
293-297: RenamestakedSupplyRatioto match the actual formula.Line 296 computes
ps / ts, which is a pool-to-staked multiplier, not a staked ratio. Renaming would reduce future inversion mistakes.🧹 Naming-only cleanup
- const stakedSupplyRatio = ts > 0 ? ps / ts : 0; + const poolToStakedRatio = ts > 0 ? ps / ts : 0; ... - stakedSupplyRatio * + poolToStakedRatio *Also applies to: 304-304
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@supernova-amm/index.js` around lines 293 - 297, The variable stakedSupplyRatio is misnamed because it computes ps/ts (poolSupply/totalSupply); rename it to something like poolShareOfTotal or poolToTotalRatio (e.g., replace stakedSupplyRatio with poolShareOfTotal) and update all usages (including the other occurrence mentioned around the later computation) so the name matches the actual formula using totalSupply and poolSupply (ts/ps variables totalSupply, poolSupply and any references in reward calculation logic).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@supernova-amm/index.js`:
- Around line 22-23: The GraphQL queries hard-code pairs(first: 1000, ...) which
truncates results; replace those single-shot queries (the pairs(...) calls
present in this file) with a paginated fetch loop that requests batches of 1000
using either cursor/last-id or skip (e.g., first:1000, skip:offset) and
continues incrementing offset until a returned batch is <1000; ensure you
preserve the same orderBy/reserveUSD sorting between calls and aggregate results
before joining on-chain pools so no pools are missed; update all occurrences of
pairs(first: 1000, ...) in this file to use the new batching logic.
---
Nitpick comments:
In `@supernova-amm/index.js`:
- Around line 293-297: The variable stakedSupplyRatio is misnamed because it
computes ps/ts (poolSupply/totalSupply); rename it to something like
poolShareOfTotal or poolToTotalRatio (e.g., replace stakedSupplyRatio with
poolShareOfTotal) and update all usages (including the other occurrence
mentioned around the later computation) so the name matches the actual formula
using totalSupply and poolSupply (ts/ps variables totalSupply, poolSupply and
any references in reward calculation logic).
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
supernova-amm/abiGauge.jsonsupernova-amm/abiPool.jsonsupernova-amm/abiPoolsFactory.jsonsupernova-amm/abiVoter.jsonsupernova-amm/index.js
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/adaptors/supernova-amm/index.js (1)
90-91: Use indexed maps instead of repeated.find()scans.Both pool-delta lookup and subgraph TVL join currently do repeated linear searches inside loops. Pre-index by
idto reduce avoidable O(n²) work.♻️ Refactor sketch
- for (const p of dataNow) { + const priorById = new Map(dataPrior.map((i) => [i.id, i])); + const prior7dById = new Map(dataPrior7d.map((i) => [i.id, i])); + for (const p of dataNow) { @@ - const p1d = dataPrior.find((i) => i.id === p.id); - const p7d = dataPrior7d.find((i) => i.id === p.id); + const p1d = priorById.get(p.id); + const p7d = prior7dById.get(p.id);- const pools = validPools.map((p, i) => { + const subgraphById = new Map( + subgraphPairs.map((sp) => [sp.id.toLowerCase(), sp]) + ); + const pools = validPools.map((p, i) => { @@ - const spr = subgraphPairs.find(sp => sp.id.toLowerCase() === p.toLowerCase()); + const spr = subgraphById.get(p.toLowerCase());Also applies to: 285-291
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/adaptors/supernova-amm/index.js` around lines 90 - 91, The loop is performing repeated O(n) .find() lookups (e.g., const p1d = dataPrior.find((i) => i.id === p.id); const p7d = dataPrior7d.find((i) => i.id === p.id);), causing quadratic behavior; fix by pre-indexing those arrays into maps (e.g., const priorById = new Map(dataPrior.map(i=>[i.id,i])) and const prior7dById = new Map(dataPrior7d.map(i=>[i.id,i]))) and then replace .find(...) with direct lookups (priorById.get(p.id), prior7dById.get(p.id)); apply the same change to the other repeated-find sites mentioned (around the TVL join at the 285–291 region) so all id-based joins use O(1) map lookups instead of .find().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/adaptors/supernova-amm/index.js`:
- Around line 232-243: The getGaugeApy function currently allows upstream
failures (coins.llama.fi axios requests and subgraph TVL calls) to throw and
crash main; wrap each external fetch in try/catch blocks (e.g., the axios.get
call that builds pricesA and any subgraph/tvl fetches used later) and on error
log the exception and return or set safe defaults so reward APY falls back to 0
instead of bubbling the error; ensure the function returns a numeric 0 APY when
fetches fail and preserves existing behavior on success (reference getGaugeApy,
the axios.get to "https://coins.llama.fi/prices/current/${x}", the pricesA
aggregation, and any TVL/subgraph fetch calls mentioned around the later
ranges).
---
Nitpick comments:
In `@src/adaptors/supernova-amm/index.js`:
- Around line 90-91: The loop is performing repeated O(n) .find() lookups (e.g.,
const p1d = dataPrior.find((i) => i.id === p.id); const p7d =
dataPrior7d.find((i) => i.id === p.id);), causing quadratic behavior; fix by
pre-indexing those arrays into maps (e.g., const priorById = new
Map(dataPrior.map(i=>[i.id,i])) and const prior7dById = new
Map(dataPrior7d.map(i=>[i.id,i]))) and then replace .find(...) with direct
lookups (priorById.get(p.id), prior7dById.get(p.id)); apply the same change to
the other repeated-find sites mentioned (around the TVL join at the 285–291
region) so all id-based joins use O(1) map lookups instead of .find().
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/adaptors/supernova-amm/abiGauge.jsonsrc/adaptors/supernova-amm/abiPool.jsonsrc/adaptors/supernova-amm/abiPoolsFactory.jsonsrc/adaptors/supernova-amm/abiVoter.jsonsrc/adaptors/supernova-amm/index.js
✅ Files skipped from review due to trivial changes (1)
- src/adaptors/supernova-amm/abiVoter.json
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/adaptors/supernova-amm/index.js (2)
144-163: Consider filtering by valid gauges before metadata/symbol/token universe expansion.You can reduce RPC and price-fetch surface by deriving
validPoolsfirst, then requestingmetadata,symbol, and token prices only for those pools.Also applies to: 175-187, 219-226
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/adaptors/supernova-amm/index.js` around lines 144 - 163, The code currently queries metadata and symbols for allPools; instead derive a filtered validPools (e.g., by checking gauge validity or other preconditions) before expanding the universe and use validPools instead of allPools in the multiCall invocations (symbols and metaData) and in the later token/price lookups around the blocks currently at 175-187 and 219-226; update all references (allPools -> validPools) in functions/variables like metaData, symbols, and any token price resolution so RPC and price fetches only request data for the validated pool list.
90-91: Replace repeated.find(...)joins with pre-indexed maps.Line 90/Line 91 and Line 300 do linear scans inside loops; pre-indexing snapshots/pairs avoids repeated O(n) lookups and keeps join logic cleaner.
♻️ Suggested refactor
@@ - const pools = {}; + const priorById = new Map(dataPrior.map((i) => [i.id, i])); + const prior7dById = new Map(dataPrior7d.map((i) => [i.id, i])); + const pools = {}; for (const p of dataNow) { @@ - const p1d = dataPrior.find((i) => i.id === p.id); - const p7d = dataPrior7d.find((i) => i.id === p.id); + const p1d = priorById.get(p.id); + const p7d = prior7dById.get(p.id); @@ - const pools = validPools.map((p, i) => { + const subgraphPairsById = new Map( + subgraphPairs.map((sp) => [sp.id.toLowerCase(), sp]) + ); + const pools = validPools.map((p, i) => { @@ - const spr = subgraphPairs.find(sp => sp.id.toLowerCase() === p.toLowerCase()); + const spr = subgraphPairsById.get(p.toLowerCase());Also applies to: 300-301
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/adaptors/supernova-amm/index.js` around lines 90 - 91, The code currently does repeated linear searches using dataPrior.find(...) and dataPrior7d.find(...) (producing p1d and p7d for each p), causing O(n^2) behavior; before the loop that iterates over pairs (where p is used) create maps keyed by id (e.g., priorById and prior7dById) from dataPrior and dataPrior7d, then replace the .find calls with direct lookups (e.g., priorById[p.id], prior7dById[p.id]); apply the same change to the other occurrence around lines 300-301 so all joins use O(1) map access instead of repeated .find.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/adaptors/supernova-amm/index.js`:
- Around line 144-163: The code currently queries metadata and symbols for
allPools; instead derive a filtered validPools (e.g., by checking gauge validity
or other preconditions) before expanding the universe and use validPools instead
of allPools in the multiCall invocations (symbols and metaData) and in the later
token/price lookups around the blocks currently at 175-187 and 219-226; update
all references (allPools -> validPools) in functions/variables like metaData,
symbols, and any token price resolution so RPC and price fetches only request
data for the validated pool list.
- Around line 90-91: The code currently does repeated linear searches using
dataPrior.find(...) and dataPrior7d.find(...) (producing p1d and p7d for each
p), causing O(n^2) behavior; before the loop that iterates over pairs (where p
is used) create maps keyed by id (e.g., priorById and prior7dById) from
dataPrior and dataPrior7d, then replace the .find calls with direct lookups
(e.g., priorById[p.id], prior7dById[p.id]); apply the same change to the other
occurrence around lines 300-301 so all joins use O(1) map access instead of
repeated .find.
Summary by CodeRabbit