Skip to content

fix(aerodrome-slipstream): use onchain calls for newer pools#2824

Merged
0xkr3p merged 1 commit into
masterfrom
fix/aerodrome-slipstream
Jul 16, 2026
Merged

fix(aerodrome-slipstream): use onchain calls for newer pools#2824
0xkr3p merged 1 commit into
masterfrom
fix/aerodrome-slipstream

Conversation

@0xkr3p

@0xkr3p 0xkr3p commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added targeted on-chain fee snapshots for pools not covered by the subgraph.
    • Improved gauge APY calculations by combining subgraph data with targeted blockchain data.
    • Added safeguards for failed data requests and pools without staked liquidity.
  • Bug Fixes

    • Improved historical fee and APY handling when subgraph coverage is incomplete.
    • Preserved timeout and conditional 24-hour snapshot behavior during fee retrieval.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Aerodrome fee snapshot supplementation

Layer / File(s) Summary
Targeted pool fee snapshot helper
src/adaptors/aerodrome-slipstream/index.js
Adds gauge-fee ABI calls and targeted multicalls for gauge fees, liquidity, and staked liquidity, excluding failed results and zeroing fees without stake.
Historical fee fetch strategy
src/adaptors/aerodrome-slipstream/index.js
Allows getGaugeApy to select full pagination or targeted fetching for pools absent from healthy subgraph results, including previous-epoch and conditional 24-hour snapshots.
APY and main integration
src/adaptors/aerodrome-slipstream/index.js
Passes subgraph pool coverage into getGaugeApy and updates the previous-snapshot extrapolation condition.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant main
  participant Subgraph
  participant getGaugeApy
  participant fetchFeesAtBlock
  participant fetchPoolFeesTargeted
  participant Multicall

  main->>Subgraph: retrieve pool coverage
  main->>getGaugeApy: pass coverage and historical-fee options
  getGaugeApy->>fetchFeesAtBlock: request historical fee snapshots
  fetchFeesAtBlock->>fetchPoolFeesTargeted: request fees for uncovered pools
  fetchPoolFeesTargeted->>Multicall: query gauge fees, liquidity, and staked liquidity
  Multicall-->>fetchPoolFeesTargeted: return per-pool results
  fetchPoolFeesTargeted-->>getGaugeApy: return targeted fee data
Loading

Suggested reviewers: slasher125

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: using on-chain calls to fill fee snapshots for pools not covered by the subgraph.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/aerodrome-slipstream

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


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 aerodrome-slipstream adapter exports pools:

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

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/adaptors/aerodrome-slipstream/index.js (1)

567-577: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Skip 24h APY calculation for subgraph-covered pools when targeted fetching is active.

Because fees24hAgo is now populated with targeted snapshots (instead of being null when historical fees are skipped), the if (fees24hAgo) condition evaluates to true for all pools.

For pools that were intentionally skipped (i.e., they are in subgraphCoveredPools), prior will be undefined, causing priorFeeUsd to default to 0. Consequently, feeDelta is calculated as currentFeeUsd (the pool's lifetime gauge fees), resulting in a massively inflated 24h APY for these covered pools.

Although main() attempts to overwrite this with the subgraph's v.apyBase, it will fall back to this inflated outlier if the subgraph returns null or undefined for a pool's APY.

Add a check to ensure covered pools bypass this calculation when historical fees are intentionally skipped.

🐛 Proposed fix
-    if (fees24hAgo) {
+    const isSkipped = skipHistoricalFees && subgraphCoveredPools?.has(lpKey);
+    if (fees24hAgo && !isSkipped) {
       const currentFeeUsd = calcFeeUsd(p);
       const prior = fees24hAgo[lpKey];
       const priorFeeUsd = prior ? calcFeeUsd(prior) : 0;
🤖 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 `@src/adaptors/aerodrome-slipstream/index.js` around lines 567 - 577, Update
the 24h APY calculation guarded by fees24hAgo to skip pools present in
subgraphCoveredPools when targeted historical fetching is active. Ensure covered
pools do not derive feeDelta, apyBase, or volumeUsd1d from a missing prior
snapshot, while preserving the existing calculation for pools with historical
fee data.
🤖 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 `@src/adaptors/aerodrome-slipstream/index.js`:
- Around line 40-42: Update the stakedLiquidity multiCall in the Slipstream
adaptor to query the gauge-side contract/helper rather than the pool ABI, while
keeping the existing liquidity and gaugeFees calls unchanged so pools with
staked liquidity are not skipped by the fallback path.

---

Outside diff comments:
In `@src/adaptors/aerodrome-slipstream/index.js`:
- Around line 567-577: Update the 24h APY calculation guarded by fees24hAgo to
skip pools present in subgraphCoveredPools when targeted historical fetching is
active. Ensure covered pools do not derive feeDelta, apyBase, or volumeUsd1d
from a missing prior snapshot, while preserving the existing calculation for
pools with historical fee data.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3cd09077-bd66-45f4-abb3-9cb4a7e7d72c

📥 Commits

Reviewing files that changed from the base of the PR and between 732246c and 4549da3.

📒 Files selected for processing (1)
  • src/adaptors/aerodrome-slipstream/index.js

Comment on lines +40 to +42
sdk.api.abi.multiCall({ abi: gaugeFeesAbi, ...opts }),
sdk.api.abi.multiCall({ abi: 'uint128:liquidity', ...opts }),
sdk.api.abi.multiCall({ abi: 'uint128:stakedLiquidity', ...opts }),

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

"stakedLiquidity" "Aerodrome" slipstream pool

💡 Result:

Slipstream is Aerodrome Finance's concentrated liquidity implementation on the Base network, designed to function similarly to Uniswap V3 [1][2][3]. In Slipstream pools, liquidity providers (LPs) choose specific price ranges for their deposits, which concentrates capital and improves fee efficiency within those ranges [2][4][5]. Staking liquidity in Slipstream pools is a mandatory step to maximize rewards [5]. Because Slipstream positions are represented as non-fungible tokens (NFTs) rather than fungible LP tokens, LPs must stake their NFT position into the corresponding pool gauge [2][4]. Key aspects of staking for Slipstream pools include: Mandatory Staking: Unstaked positions do not receive AERO emissions and result in the protocol withholding a portion (approximately 10%) of earned swap fees, which are then distributed to veAERO voters [4][5]. Mechanism: After depositing liquidity and receiving an NFT representing that position, users must stake the NFT via the Aerodrome interface [2][4][5]. Rewards: Staked positions are eligible for a "triple income stream": Trading fees accrued while the position remains within the active price range [2][4][5]. AERO emissions distributed through the gauge [4][5]. Additional rewards (bribes) from veAERO voters [5]. Management: Because Slipstream pools concentrate liquidity, positions require active monitoring [2]. If the market price exits the selected range, the position stops earning swap fees until the price returns to that range or the LP adjusts it [2][4][5]. For more technical details, including integration interfaces and contract addresses, the official Aerodrome Finance GitHub repository maintains the specification and core contracts for Slipstream [1][6][7].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the relevant file and any nearby references to stakedLiquidity / liquidity fields.
git ls-files src/adaptors/aerodrome-slipstream index.js src/adaptors/aerodrome-slipstream
printf '\n--- index.js outline ---\n'
ast-grep outline src/adaptors/aerodrome-slipstream/index.js --view expanded || true
printf '\n--- occurrences ---\n'
rg -n "stakedLiquidity|liquidity|gaugeFeesAbi|multiCall" src/adaptors/aerodrome-slipstream src/adaptors -g '!**/node_modules/**' || true
printf '\n--- file excerpt ---\n'
cat -n src/adaptors/aerodrome-slipstream/index.js | sed -n '1,160p'

Repository: DefiLlama/yield-server

Length of output: 50379


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file=src/adaptors/aerodrome-slipstream/index.js
printf '%s\n' "--- ${file} (1-180) ---"
cat -n "$file" | sed -n '1,180p'

printf '\n--- direct matches in %s ---\n' "$file"
rg -n "stakedLiquidity|liquidity|gaugeFeesAbi|pool|gauge" "$file" || true

printf '\n--- nearby adaptor files mentioning aerodrome-slipstream ---\n'
rg -n "aerodrome-slipstream|stakedLiquidity" src/adaptors -g '!**/node_modules/**' | sed -n '1,120p' || true

Repository: DefiLlama/yield-server

Length of output: 12564


🌐 Web query:

"Aerodrome Slipstream" stakedLiquidity function pool ABI

💡 Result:

In Aerodrome Slipstream, there is no single function named stakedLiquidity defined in the core pool contract ABI [1][2]. Aerodrome Slipstream is a concentrated liquidity AMM (based on the Uniswap V3 architecture) where liquidity is managed via non-fungible position tokens (ERC-721 NFTs) [1][2][3]. The concept of "staked liquidity" refers to these NFT positions being deposited into a Gauge contract to earn AERO emissions [2]. To retrieve information related to staked liquidity, you must interact with the relevant Gauge contract and the NonfungiblePositionManager, rather than a single pool function [2]: 1. To check if a position is staked: You typically interact with the Gauge contract, which handles the staking of position NFTs [2]. 2. To calculate or view liquidity amounts: You query the NonfungiblePositionManager's positions(uint256 tokenId) function to get the position details, including the liquidity amount [4][5]. 3. For APR/Reward calculations: These are often derived by aggregating total staked liquidity within the gauge, which is documented at the pool/gauge level [6][7]. Because Slipstream follows the Concentrated Liquidity standard, the ABI for the pool itself exposes standard functions such as mint, burn, collect, and position management [1], while staking logic is externalized to the Gauge system [2]. If you are looking for specific data (like total staked liquidity), you should query the Gauge contract's view functions or use a protocol-specific subgraph/indexer that tracks gauge deposits [2][7].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file=src/adaptors/aerodrome-slipstream/index.js

printf '%s\n' '--- pool/gauge target wiring around targeted fees ---'
sed -n '300,460p' "$file" | cat -n

printf '\n%s\n' '--- where fetchPoolFeesTargeted is called ---'
rg -n "fetchPoolFeesTargeted|fetchPoolFeesAtBlock|gaugeFees|stakedLiquidity" "$file" src/adaptors/aerodrome-slipstream -g '!**/node_modules/**'

printf '\n%s\n' '--- any ABI references for stakedLiquidity in repo ---'
rg -n '"stakedLiquidity"|stakedLiquidity\(' src/adaptors -g '!**/node_modules/**' | sed -n '1,120p' || true

Repository: DefiLlama/yield-server

Length of output: 8217


Use the gauge for stakedLiquidity
stakedLiquidity() isn’t part of the Slipstream pool ABI; query the gauge-side contract/helper here instead, or the fallback path will skip these pools.

🤖 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 `@src/adaptors/aerodrome-slipstream/index.js` around lines 40 - 42, Update the
stakedLiquidity multiCall in the Slipstream adaptor to query the gauge-side
contract/helper rather than the pool ABI, while keeping the existing liquidity
and gaugeFees calls unchanged so pools with staked liquidity are not skipped by
the fallback path.

@0xkr3p
0xkr3p merged commit d828858 into master Jul 16, 2026
2 checks passed
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.

1 participant