Skip to content

Add Curvance#2480

Open
iamvukasin wants to merge 2 commits intoDefiLlama:masterfrom
iamvukasin:curvance
Open

Add Curvance#2480
iamvukasin wants to merge 2 commits intoDefiLlama:masterfrom
iamvukasin:curvance

Conversation

@iamvukasin
Copy link
Contributor

@iamvukasin iamvukasin commented Mar 13, 2026

Summary by CodeRabbit

  • New Features
    • Curvance pool integration: surfaces market analytics — TVL (USD), APY (supply and conditional borrow), total supply/borrow, borrowable status, underlying tokens, and pool links across multiple chains.
    • Improved data fidelity: retrieves detailed dynamic on-chain market data and batched price lookups to compute APY and USD valuations more accurately.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 13, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a Curvance adapter and an ABI module. src/adaptors/curvance/abi.js exports getDynamicMarketDataAbi; src/adaptors/curvance/index.js implements chain-aware market discovery, on-chain + price fetching, and per-pool TVL/APY computations.

Changes

Cohort / File(s) Summary
Curvance ABI Definition
src/adaptors/curvance/abi.js
New module exporting getDynamicMarketDataAbi — ABI for getDynamicMarketData() returning a tuple[] with nested tokens[] and multiple uint256 fields.
Curvance Pool Adapter
src/adaptors/curvance/index.js
New adapter exporting { timetravel: false, apy: main, url }. Discovers market managers per chain, enumerates markets, fetches on-chain dynamic data and token metadata, batches price queries, computes TVL, APY, supply/borrow metrics, and returns normalized pool objects.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant Adapter as Curvance Adapter
    participant Registry as Central Registry
    participant Manager as Market Manager
    participant Chain as On-chain Contracts
    participant PriceSvc as Price Service

    Caller->>Adapter: apy(chainId)
    Adapter->>Registry: getMarketManagers(chainId)
    Registry-->>Adapter: managers[]

    loop per manager
        Adapter->>Manager: getMarkets()
        Manager-->>Adapter: markets[]
        loop per market
            Adapter->>Chain: getDynamicMarketData(market) (ABI)
            Chain-->>Adapter: dynamicData
            Adapter->>Chain: getUnderlyingToken(market)
            Chain-->>Adapter: tokenAddress
            Adapter->>Chain: getTokenMetadata(tokenAddress)
            Chain-->>Adapter: symbol, decimals
        end
    end

    Adapter->>PriceSvc: batchQueryPrices(underlyingTokens)
    PriceSvc-->>Adapter: prices{}
    Adapter->>Adapter: compute TVL, APY, supply/borrow metrics
    Adapter-->>Caller: pools[]
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I nibble ABIs and hop through chains,
I fetch the tokens, prices, and tiny gains,
I tally TVL and APY with a twitchy paw,
Pool by pool I hop — what a lawful draw! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add Curvance' directly matches the primary change: adding a new Curvance adapter that exports pools and metrics.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

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 and usage tips.

Tip

You can customize the high-level summary generated by CodeRabbit.

Configure the reviews.high_level_summary_instructions setting to provide custom instructions for generating the high-level summary.

@llamatester
Copy link

The curvance adapter exports pools:

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

Nb of pools: 32
 

Sample pools:
┌─────────┬────────────────────────────────────────────────────┬─────────┬────────────┬────────────┬────────────────────┬────────────────────┬─────────────────┬──────────────────────────────────────────────────┬────────────────────────────┬────────────────────┬────────────────────┬───────────────────┬────────────┐
│ (index) │ pool                                               │ chain   │ project    │ symbol     │ tvlUsd             │ apyBase            │ poolMeta        │ underlyingTokens                                 │ url                        │ apyBaseBorrow      │ totalSupplyUsd     │ totalBorrowUsd    │ borrowable │
├─────────┼────────────────────────────────────────────────────┼─────────┼────────────┼────────────┼────────────────────┼────────────────────┼─────────────────┼──────────────────────────────────────────────────┼────────────────────────────┼────────────────────┼────────────────────┼───────────────────┼────────────┤
│ 0       │ '0x852ff1ec21d63b405ec431e04ae3ac760e29263d-monad' │ 'Monad' │ 'curvance' │ 'EARNAUSD' │ 18472602.208878566 │ 0                  │ 'earnAUSD/AUSD' │ [ '0x103222f020e98Bba0AD9809A011FDF8e6F067496' ] │ 'https://app.curvance.com' │                    │                    │                   │            │
│ 1       │ '0x7eda3cb060ff7b650eb227971dbfebd3513b11d5-monad' │ 'Monad' │ 'curvance' │ 'SYZUSD'   │ 5271392.93947617   │ 0                  │ 'syzUSD/AUSD'   │ [ '0x484be0540aD49f351eaa04eeB35dF0f937D4E73f' ] │ 'https://app.curvance.com' │                    │                    │                   │            │
│ 2       │ '0xad4aa2a713fb86fbb6b60de2af9e32a11db6abf2-monad' │ 'Monad' │ 'curvance' │ 'AUSD'     │ 3016662.026480623  │ 6.3640239962256    │ 'earnAUSD/AUSD' │ [ '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a' ] │ 'https://app.curvance.com' │ 8.8638703446528    │ 14915387.565094601 │ 11898725.53861398 │ true       │
│ 3       │ '0x20f1a13bfbf85a22aa59d189861790981372220b-monad' │ 'Monad' │ 'curvance' │ 'EZETH'    │ 2713812.426006979  │ 0                  │ 'ezETH/WETH'    │ [ '0x2416092f143378750bb29b79eD961ab195CcEea5' ] │ 'https://app.curvance.com' │                    │                    │                   │            │
│ 4       │ '0x8626b8f4f64caeee9549af8ebbfa591a7425e5ba-monad' │ 'Monad' │ 'curvance' │ 'YZM'      │ 1237175.351388697  │ 0                  │ 'YZM/AUSD'      │ [ '0x3a2c4aAae6776dC1c31316De559598f2f952E2cB' ] │ 'https://app.curvance.com' │                    │                    │                   │            │
│ 5       │ '0xa206d51c02c0202a2eed8e6a757b49ab13930227-monad' │ 'Monad' │ 'curvance' │ 'WETH'     │ 1046405.1089781985 │ 2.3836080078576    │ 'ezETH/WETH'    │ [ '0xEE8c0E9f1BFFb4Eb878d8f15f368A02a35481242' ] │ 'https://app.curvance.com' │ 3.8358349390080004 │ 3380410.553639099  │ 2334005.444660901 │ true       │
│ 6       │ '0x8ee9fc28b8da872c38a496e9ddb9700bb7261774-monad' │ 'Monad' │ 'curvance' │ 'USDC'     │ 943045.0039730775  │ 1.9880893426319997 │ 'WMON/USDC'     │ [ '0x754704Bc059F8C67012fEd69BC8A327a5aafb603' ] │ 'https://app.curvance.com' │ 5.584417175952     │ 1560203.6638888677 │ 617158.6599157902 │ true       │
│ 7       │ '0x8e94704607e857eb3e10bd21d90bf8c1ecba0452-monad' │ 'Monad' │ 'curvance' │ 'AUSD'     │ 740316.3996194225  │ 5.844063373070401  │ 'syzUSD/AUSD'   │ [ '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a' ] │ 'https://app.curvance.com' │ 7.5973116576528    │ 5095003.286339111  │ 4354686.886719688 │ true       │
│ 8       │ '0x92ee4b4d33dc61bd93a88601f29131b08acedbf1-monad' │ 'Monad' │ 'curvance' │ 'MUBOND'   │ 655794.0158659052  │ 0                  │ 'muBOND/AUSD'   │ [ '0x336D414754967C6682B5A665C7DAF6F1409E63e8' ] │ 'https://app.curvance.com' │                    │                    │                   │            │
│ 9       │ '0x926c101cf0a3de8725eb24a93e980f9fe34d6230-monad' │ 'Monad' │ 'curvance' │ 'SHMON'    │ 625485.9556223963  │ 0                  │ 'shMON/WMON'    │ [ '0x1B68626dCa36c7fE922fD2d55E4f631d962dE19c' ] │ 'https://app.curvance.com' │                    │                    │                   │            │
└─────────┴────────────────────────────────────────────────────┴─────────┴────────────┴────────────┴────────────────────┴────────────────────┴─────────────────┴──────────────────────────────────────────────────┴────────────────────────────┴────────────────────┴────────────────────┴───────────────────┴────────────┘
This adapter contains some pools with <10k TVL, these pools won't be shown in DefiLlama

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@src/adaptors/curvance/index.js`:
- Around line 169-170: The statement building poolMeta is missing a trailing
semicolon; update the assignment to poolMeta (the line using
managerSymbols[manager].join("/")) to terminate the statement with a semicolon
so the two consecutive statements (const manager =
marketToManager[market.toLowerCase()]; and const poolMeta =
managerSymbols[manager].join("/");) are properly separated.
- Around line 78-84: The multiCall using sdk.api.abi.multiCall (the
underlyingRes variable) uses permitFailure: true, so each result element is
{success, output}; update the code that builds underlyings from
underlyingRes.output to only use outputs where success is true (e.g., map/filter
the underlyingRes.output array or reduce to extract output when success) and
handle/skip failed calls (or provide a sensible default) so undefined outputs
don't propagate; apply the same fix to the other multiCall usages that
destructure output directly (the subsequent calls that build
borrowRates/underlyings at the later multiCall sites).
- Around line 144-189: The map callback over markets currently returns null for
entries missing required data (inside the markets.map(...) block where it checks
if (!symbol || !underlying || !price) return null), but those nulls are left in
the returned array; update the code that returns the mapped array to filter out
null results (e.g., apply a .filter(...) after the markets.map call or replace
map with a combined flatMap) so the final returned value contains only the pool
objects (with fields like pool, chain, tvlUsd, apyBase, etc.) and no nulls.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 33f5da8c-eab7-4429-8ae0-412091d31e01

📥 Commits

Reviewing files that changed from the base of the PR and between 2174e93 and 34e858c.

📒 Files selected for processing (2)
  • src/adaptors/curvance/abi.js
  • src/adaptors/curvance/index.js

@llamatester
Copy link

The curvance adapter exports pools:

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

Nb of pools: 32
 

Sample pools:
┌─────────┬────────────────────────────────────────────────────┬─────────┬────────────┬────────────┬────────────────────┬────────────────────┬─────────────────┬──────────────────────────────────────────────────┬────────────────────────────┬────────────────────┬────────────────────┬───────────────────┬────────────┐
│ (index) │ pool                                               │ chain   │ project    │ symbol     │ tvlUsd             │ apyBase            │ poolMeta        │ underlyingTokens                                 │ url                        │ apyBaseBorrow      │ totalSupplyUsd     │ totalBorrowUsd    │ borrowable │
├─────────┼────────────────────────────────────────────────────┼─────────┼────────────┼────────────┼────────────────────┼────────────────────┼─────────────────┼──────────────────────────────────────────────────┼────────────────────────────┼────────────────────┼────────────────────┼───────────────────┼────────────┤
│ 0       │ '0x852ff1ec21d63b405ec431e04ae3ac760e29263d-monad' │ 'Monad' │ 'curvance' │ 'EARNAUSD' │ 18495543.08226336  │ 0                  │ 'earnAUSD/AUSD' │ [ '0x103222f020e98Bba0AD9809A011FDF8e6F067496' ] │ 'https://app.curvance.com' │                    │                    │                   │            │
│ 1       │ '0x7eda3cb060ff7b650eb227971dbfebd3513b11d5-monad' │ 'Monad' │ 'curvance' │ 'SYZUSD'   │ 5274378.673665184  │ 0                  │ 'syzUSD/AUSD'   │ [ '0x484be0540aD49f351eaa04eeB35dF0f937D4E73f' ] │ 'https://app.curvance.com' │                    │                    │                   │            │
│ 2       │ '0xad4aa2a713fb86fbb6b60de2af9e32a11db6abf2-monad' │ 'Monad' │ 'curvance' │ 'AUSD'     │ 2797571.2859007847 │ 6.561290944655999  │ 'earnAUSD/AUSD' │ [ '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a' ] │ 'https://app.curvance.com' │ 9.000199548648     │ 14725451.312896194 │ 11927880.02699541 │ true       │
│ 3       │ '0x20f1a13bfbf85a22aa59d189861790981372220b-monad' │ 'Monad' │ 'curvance' │ 'EZETH'    │ 2713812.426006979  │ 0                  │ 'ezETH/WETH'    │ [ '0x2416092f143378750bb29b79eD961ab195CcEea5' ] │ 'https://app.curvance.com' │                    │                    │                   │            │
│ 4       │ '0x8626b8f4f64caeee9549af8ebbfa591a7425e5ba-monad' │ 'Monad' │ 'curvance' │ 'YZM'      │ 1237175.351388697  │ 0                  │ 'YZM/AUSD'      │ [ '0x3a2c4aAae6776dC1c31316De559598f2f952E2cB' ] │ 'https://app.curvance.com' │                    │                    │                   │            │
│ 5       │ '0xa206d51c02c0202a2eed8e6a757b49ab13930227-monad' │ 'Monad' │ 'curvance' │ 'WETH'     │ 1046405.1089781985 │ 2.3836080078576    │ 'ezETH/WETH'    │ [ '0xEE8c0E9f1BFFb4Eb878d8f15f368A02a35481242' ] │ 'https://app.curvance.com' │ 3.8358349390080004 │ 3380410.553639099  │ 2334005.444660901 │ true       │
│ 6       │ '0x8ee9fc28b8da872c38a496e9ddb9700bb7261774-monad' │ 'Monad' │ 'curvance' │ 'USDC'     │ 943079.1821811267  │ 1.9880893426319997 │ 'WMON/USDC'     │ [ '0x754704Bc059F8C67012fEd69BC8A327a5aafb603' ] │ 'https://app.curvance.com' │ 5.584417175952     │ 1560260.2094038737 │ 617181.027222747  │ true       │
│ 7       │ '0x8e94704607e857eb3e10bd21d90bf8c1ecba0452-monad' │ 'Monad' │ 'curvance' │ 'AUSD'     │ 740814.2297913994  │ 5.844063373070401  │ 'syzUSD/AUSD'   │ [ '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a' ] │ 'https://app.curvance.com' │ 7.5973116576528    │ 5098429.451642979  │ 4357615.22185158  │ true       │
│ 8       │ '0x92ee4b4d33dc61bd93a88601f29131b08acedbf1-monad' │ 'Monad' │ 'curvance' │ 'MUBOND'   │ 655794.0158659052  │ 0                  │ 'muBOND/AUSD'   │ [ '0x336D414754967C6682B5A665C7DAF6F1409E63e8' ] │ 'https://app.curvance.com' │                    │                    │                   │            │
│ 9       │ '0x926c101cf0a3de8725eb24a93e980f9fe34d6230-monad' │ 'Monad' │ 'curvance' │ 'SHMON'    │ 636426.1763131157  │ 0                  │ 'shMON/WMON'    │ [ '0x1B68626dCa36c7fE922fD2d55E4f631d962dE19c' ] │ 'https://app.curvance.com' │                    │                    │                   │            │
└─────────┴────────────────────────────────────────────────────┴─────────┴────────────┴────────────┴────────────────────┴────────────────────┴─────────────────┴──────────────────────────────────────────────────┴────────────────────────────┴────────────────────┴────────────────────┴───────────────────┴────────────┘
This adapter contains some pools with <10k TVL, these pools won't be shown in DefiLlama

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/adaptors/curvance/index.js (1)

27-29: Consider adding timeout protection for external price requests.

The axios.get call here lacks a timeout. While this is consistent with most other adapters in the codebase, adding timeout protection would be a defensive improvement to prevent potential hung requests from stalling the adapter.

Suggested improvement
   for (let i = 0; i < addresses.length; i += chunkSize) {
     const chunk = addresses.slice(i, i + chunkSize);
+    const timeoutMs = 10_000;
     const { data } = await axios.get(
-      `https://coins.llama.fi/prices/current/${chunk.join(',')}`
+      `https://coins.llama.fi/prices/current/${chunk.join(',')}`,
+      { timeout: timeoutMs }
     );
     for (const [key, val] of Object.entries(data.coins)) {
       prices[key.split(':')[1].toLowerCase()] = val.price;
     }
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/adaptors/curvance/index.js` around lines 27 - 29, The axios.get call that
fetches prices (the line using axios.get with chunk.join(',')) lacks a timeout;
update that call to include a timeout option (e.g., { timeout: 5000 }) or wire
in an existing shared DEFAULT_TIMEOUT constant and use it in the axios.get
options so external price requests cannot hang indefinitely; ensure you add the
timeout to the same axios.get invocation that destructures const { data } =
await axios.get(...).
🤖 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/curvance/index.js`:
- Around line 84-111: underlyings currently includes null entries from
underlyingRes.output.map when asset calls failed, then those nulls are passed as
targets into sdk.api.abi.multiCall for symbol/decimals which can break the
multicall; filter out falsy/null addresses before building the multicall calls
(e.g., create a filteredUnderlyings = underlyings.filter(Boolean) or filter
based on underlyingRes.output success) and use filteredUnderlyings.map(...) for
the symbolRes and decimalsRes multicalls so only valid contract addresses are
passed as targets while keeping permitFailure: true.

---

Nitpick comments:
In `@src/adaptors/curvance/index.js`:
- Around line 27-29: The axios.get call that fetches prices (the line using
axios.get with chunk.join(',')) lacks a timeout; update that call to include a
timeout option (e.g., { timeout: 5000 }) or wire in an existing shared
DEFAULT_TIMEOUT constant and use it in the axios.get options so external price
requests cannot hang indefinitely; ensure you add the timeout to the same
axios.get invocation that destructures const { data } = await axios.get(...).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ad2d2d11-6522-489e-a3bb-0c112f169bf8

📥 Commits

Reviewing files that changed from the base of the PR and between 34e858c and 960575a.

📒 Files selected for processing (1)
  • src/adaptors/curvance/index.js

@llamatester
Copy link

The curvance adapter exports pools:

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

Nb of pools: 32
 

Sample pools:
┌─────────┬────────────────────────────────────────────────────┬─────────┬────────────┬────────────┬────────────────────┬─────────────────┬─────────────────┬──────────────────────────────────────────────────┬────────────────────────────┬────────────────────┬────────────────────┬────────────────────┬────────────┐
│ (index) │ pool                                               │ chain   │ project    │ symbol     │ tvlUsd             │ apyBase         │ poolMeta        │ underlyingTokens                                 │ url                        │ apyBaseBorrow      │ totalSupplyUsd     │ totalBorrowUsd     │ borrowable │
├─────────┼────────────────────────────────────────────────────┼─────────┼────────────┼────────────┼────────────────────┼─────────────────┼─────────────────┼──────────────────────────────────────────────────┼────────────────────────────┼────────────────────┼────────────────────┼────────────────────┼────────────┤
│ 0       │ '0x852ff1ec21d63b405ec431e04ae3ac760e29263d-monad' │ 'Monad' │ 'curvance' │ 'EARNAUSD' │ 18504937.51439356  │ 0               │ 'earnAUSD/AUSD' │ [ '0x103222f020e98Bba0AD9809A011FDF8e6F067496' ] │ 'https://app.curvance.com' │                    │                    │                    │            │
│ 1       │ '0x7eda3cb060ff7b650eb227971dbfebd3513b11d5-monad' │ 'Monad' │ 'curvance' │ 'SYZUSD'   │ 5266321.6310263015 │ 0               │ 'syzUSD/AUSD'   │ [ '0x484be0540aD49f351eaa04eeB35dF0f937D4E73f' ] │ 'https://app.curvance.com' │                    │                    │                    │            │
│ 2       │ '0xad4aa2a713fb86fbb6b60de2af9e32a11db6abf2-monad' │ 'Monad' │ 'curvance' │ 'AUSD'     │ 2797871.8865846456 │ 6.561098133552  │ 'earnAUSD/AUSD' │ [ '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a' ] │ 'https://app.curvance.com' │ 9.0000673087392    │ 14726111.040294874 │ 11928239.15371023  │ true       │
│ 3       │ '0x20f1a13bfbf85a22aa59d189861790981372220b-monad' │ 'Monad' │ 'curvance' │ 'EZETH'    │ 2741670.834507288  │ 0               │ 'ezETH/WETH'    │ [ '0x2416092f143378750bb29b79eD961ab195CcEea5' ] │ 'https://app.curvance.com' │                    │                    │                    │            │
│ 4       │ '0x8e94704607e857eb3e10bd21d90bf8c1ecba0452-monad' │ 'Monad' │ 'curvance' │ 'AUSD'     │ 1346678.3267798987 │ 4.668262112088  │ 'syzUSD/AUSD'   │ [ '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a' ] │ 'https://app.curvance.com' │ 6.790161446352     │ 5703682.04732033   │ 4357003.72054043   │ true       │
│ 5       │ '0x8626b8f4f64caeee9549af8ebbfa591a7425e5ba-monad' │ 'Monad' │ 'curvance' │ 'YZM'      │ 1237292.3793541286 │ 0               │ 'YZM/AUSD'      │ [ '0x3a2c4aAae6776dC1c31316De559598f2f952E2cB' ] │ 'https://app.curvance.com' │                    │                    │                    │            │
│ 6       │ '0xa206d51c02c0202a2eed8e6a757b49ab13930227-monad' │ 'Monad' │ 'curvance' │ 'WETH'     │ 1057263.316850524  │ 2.3836080078576 │ 'ezETH/WETH'    │ [ '0xEE8c0E9f1BFFb4Eb878d8f15f368A02a35481242' ] │ 'https://app.curvance.com' │ 3.8358349390080004 │ 3415487.982227973  │ 2358224.6653774497 │ true       │
│ 7       │ '0x8ee9fc28b8da872c38a496e9ddb9700bb7261774-monad' │ 'Monad' │ 'curvance' │ 'USDC'     │ 931061.4453561375  │ 2.0190186183744 │ 'WMON/USDC'     │ [ '0x754704Bc059F8C67012fEd69BC8A327a5aafb603' ] │ 'https://app.curvance.com' │ 5.627688718089599  │ 1548228.6661175056 │ 617167.2207613684  │ true       │
│ 8       │ '0x92ee4b4d33dc61bd93a88601f29131b08acedbf1-monad' │ 'Monad' │ 'curvance' │ 'MUBOND'   │ 655365.1980842976  │ 0               │ 'muBOND/AUSD'   │ [ '0x336D414754967C6682B5A665C7DAF6F1409E63e8' ] │ 'https://app.curvance.com' │                    │                    │                    │            │
│ 9       │ '0x926c101cf0a3de8725eb24a93e980f9fe34d6230-monad' │ 'Monad' │ 'curvance' │ 'SHMON'    │ 642592.4980978062  │ 0               │ 'shMON/WMON'    │ [ '0x1B68626dCa36c7fE922fD2d55E4f631d962dE19c' ] │ 'https://app.curvance.com' │                    │                    │                    │            │
└─────────┴────────────────────────────────────────────────────┴─────────┴────────────┴────────────┴────────────────────┴─────────────────┴─────────────────┴──────────────────────────────────────────────────┴────────────────────────────┴────────────────────┴────────────────────┴────────────────────┴────────────┘
This adapter contains some pools with <10k TVL, these pools won't be shown in DefiLlama

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/adaptors/curvance/index.js (1)

63-72: Consider explicit success check for market list calls.

Line 67 uses || [] as a fallback, which prevents crashes, but an explicit success check would be more consistent with the pattern used elsewhere in this file (lines 84-86, 131-132).

♻️ Optional improvement for consistency
   for (let i = 0; i < managers.length; i++) {
-    const list = marketsRes.output[i].output || [];
+    const res = marketsRes.output[i];
+    const list = res?.success ? res.output : [];
     for (const addr of list) {
       markets.push(addr);
       marketToManager[addr.toLowerCase()] = managers[i].toLowerCase();
     }
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/adaptors/curvance/index.js` around lines 63 - 72, The code currently uses
a silent fallback (marketsRes.output[i].output || []) which masks failed
market-list calls; update the loop that builds markets and marketToManager to
explicitly check marketsRes.output[i].success (or equivalent success flag)
before reading output, skip or handle failed entries (e.g., log/continue)
instead of using the || [] fallback, and only iterate the returned output when
success is true; reference the variables marketToManager, markets, managers and
marketsRes.output to locate and update the 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 `@src/adaptors/curvance/index.js`:
- Around line 18-35: getPrices lacks error handling around the axios.get call so
a failing coins.llama.fi request will throw and break the adapter; wrap the
per-chunk network call in a try/catch inside getPrices, log the error (or emit
via existing logger) and continue processing remaining chunks, and for any
tokens in the failed chunk either skip them or set their price to null/NaN in
the prices object so callers can handle missing prices; ensure you reference the
chunk variable and preserve chunkSize/addresses looping behavior when
implementing the try/catch and optional retry/backoff logic.
- Around line 44-54: In getPoolsForChain, the response from sdk.api.abi.call
(managersRes) is used without checking its success flag when permitFailure:
true; update the logic to verify managersRes exists and managersRes.success is
true before reading managersRes.output (e.g., treat failures by returning an
empty array or handling the error), and ensure any early-return or logging
occurs when managersRes.success is false so managers is never dereferenced when
the call failed.

---

Nitpick comments:
In `@src/adaptors/curvance/index.js`:
- Around line 63-72: The code currently uses a silent fallback
(marketsRes.output[i].output || []) which masks failed market-list calls; update
the loop that builds markets and marketToManager to explicitly check
marketsRes.output[i].success (or equivalent success flag) before reading output,
skip or handle failed entries (e.g., log/continue) instead of using the || []
fallback, and only iterate the returned output when success is true; reference
the variables marketToManager, markets, managers and marketsRes.output to locate
and update the logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fccdc139-b36a-4b50-af0a-292e0e9f8d54

📥 Commits

Reviewing files that changed from the base of the PR and between 960575a and 30f1875.

📒 Files selected for processing (1)
  • src/adaptors/curvance/index.js

Minor fixes

Avoid using null targets

Error handling for price fetching
@llamatester
Copy link

The curvance adapter exports pools:

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

Nb of pools: 34
 

Sample pools:
┌─────────┬────────────────────────────────────────────────────┬─────────┬────────────┬────────────┬────────────────────┬────────────────────┬─────────────────┬──────────────────────────────────────────────────┬────────────────────────────┬───────────────────┬────────────────────┬────────────────────┬────────────┐
│ (index) │ pool                                               │ chain   │ project    │ symbol     │ tvlUsd             │ apyBase            │ poolMeta        │ underlyingTokens                                 │ url                        │ apyBaseBorrow     │ totalSupplyUsd     │ totalBorrowUsd     │ borrowable │
├─────────┼────────────────────────────────────────────────────┼─────────┼────────────┼────────────┼────────────────────┼────────────────────┼─────────────────┼──────────────────────────────────────────────────┼────────────────────────────┼───────────────────┼────────────────────┼────────────────────┼────────────┤
│ 0       │ '0x852ff1ec21d63b405ec431e04ae3ac760e29263d-monad' │ 'Monad' │ 'curvance' │ 'EARNAUSD' │ 17881589.041726846 │ 0                  │ 'earnAUSD/AUSD' │ [ '0x103222f020e98Bba0AD9809A011FDF8e6F067496' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
│ 1       │ '0x7eda3cb060ff7b650eb227971dbfebd3513b11d5-monad' │ 'Monad' │ 'curvance' │ 'SYZUSD'   │ 5801701.719928938  │ 0                  │ 'syzUSD/AUSD'   │ [ '0x484be0540aD49f351eaa04eeB35dF0f937D4E73f' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
│ 2       │ '0xad4aa2a713fb86fbb6b60de2af9e32a11db6abf2-monad' │ 'Monad' │ 'curvance' │ 'AUSD'     │ 3735276.268094713  │ 5.804033375376001  │ 'earnAUSD/AUSD' │ [ '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a' ] │ 'https://app.curvance.com' │ 8.464911874459201 │ 15684030.550661433 │ 11948754.28256672  │ true       │
│ 3       │ '0x20f1a13bfbf85a22aa59d189861790981372220b-monad' │ 'Monad' │ 'curvance' │ 'EZETH'    │ 3090098.067922772  │ 0                  │ 'ezETH/WETH'    │ [ '0x2416092f143378750bb29b79eD961ab195CcEea5' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
│ 4       │ '0x8626b8f4f64caeee9549af8ebbfa591a7425e5ba-monad' │ 'Monad' │ 'curvance' │ 'YZM'      │ 1947638.2150274608 │ 0                  │ 'YZM/AUSD'      │ [ '0x3a2c4aAae6776dC1c31316De559598f2f952E2cB' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
│ 5       │ '0xa206d51c02c0202a2eed8e6a757b49ab13930227-monad' │ 'Monad' │ 'curvance' │ 'WETH'     │ 971824.1678789582  │ 2.6886218441184004 │ 'ezETH/WETH'    │ [ '0xEE8c0E9f1BFFb4Eb878d8f15f368A02a35481242' ] │ 'https://app.curvance.com' │ 4.0738717638432   │ 3643843.0346093625 │ 2672018.8667304046 │ true       │
│ 6       │ '0x8e94704607e857eb3e10bd21d90bf8c1ecba0452-monad' │ 'Monad' │ 'curvance' │ 'AUSD'     │ 886559.8191994616  │ 5.7193852609584    │ 'syzUSD/AUSD'   │ [ '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a' ] │ 'https://app.curvance.com' │ 7.5158336649456   │ 5739413.5338371955 │ 4852853.714637735  │ true       │
│ 7       │ '0x926c101cf0a3de8725eb24a93e980f9fe34d6230-monad' │ 'Monad' │ 'curvance' │ 'SHMON'    │ 676163.8552129667  │ 0                  │ 'shMON/WMON'    │ [ '0x1B68626dCa36c7fE922fD2d55E4f631d962dE19c' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
│ 8       │ '0x92ee4b4d33dc61bd93a88601f29131b08acedbf1-monad' │ 'Monad' │ 'curvance' │ 'MUBOND'   │ 655154.6942327527  │ 0                  │ 'muBOND/AUSD'   │ [ '0x336D414754967C6682B5A665C7DAF6F1409E63e8' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
│ 9       │ '0xf7a6ab4af86966c141d3c5633df658e5cdb0a735-monad' │ 'Monad' │ 'curvance' │ 'LOAZND'   │ 529647.6963398046  │ 0                  │ 'loAZND/AUSD'   │ [ '0x9c82eB49B51F7Dc61e22Ff347931CA32aDc6cd90' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
└─────────┴────────────────────────────────────────────────────┴─────────┴────────────┴────────────┴────────────────────┴────────────────────┴─────────────────┴──────────────────────────────────────────────────┴────────────────────────────┴───────────────────┴────────────────────┴────────────────────┴────────────┘
This adapter contains some pools with <10k TVL, these pools won't be shown in DefiLlama

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/adaptors/curvance/index.js (1)

49-56: ⚠️ Potential issue | 🟠 Major

Guard manager discovery on success when using permitFailure.

Line 55 dereferences managersRes.output directly. With permitFailure: true, failed calls should be gated on success before reading output.

Proposed fix
-  const managers = managersRes.output;
+  const managers = managersRes?.success ? managersRes.output : null;
   if (!managers || !managers.length) {
     return [];
   }
In `@defillama/sdk` v5.0.207, what is the return shape of sdk.api.abi.call when permitFailure:true and the call fails? Is `success` false with `output` unset?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/adaptors/curvance/index.js` around lines 49 - 56, The code reads
managersRes.output unguarded after calling sdk.api.abi.call with
permitFailure:true; instead, check managersRes.success (from the sdk call)
before accessing output and only set managers = managersRes.output when success
is true, otherwise handle the failed call path (e.g., log or skip) to avoid
dereferencing undefined; update the logic around the variables managersRes and
managers in the function that calls sdk.api.abi.call (the
centralRegistry/marketManagers block) to gate on managersRes.success and treat
the failure case explicitly.
🤖 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/curvance/index.js`:
- Around line 28-30: The axios.get call that fetches
`https://coins.llama.fi/prices/current/${chunk.join(',')}` is missing a request
timeout; update the call to include a timeout option (e.g. { timeout: 5000 }) so
the request fails fast on hangs, or use an axios instance with a default timeout
and replace the inline axios.get call accordingly; ensure the timeout value is
reasonable for your environment and keep the request semantics the same.

---

Duplicate comments:
In `@src/adaptors/curvance/index.js`:
- Around line 49-56: The code reads managersRes.output unguarded after calling
sdk.api.abi.call with permitFailure:true; instead, check managersRes.success
(from the sdk call) before accessing output and only set managers =
managersRes.output when success is true, otherwise handle the failed call path
(e.g., log or skip) to avoid dereferencing undefined; update the logic around
the variables managersRes and managers in the function that calls
sdk.api.abi.call (the centralRegistry/marketManagers block) to gate on
managersRes.success and treat the failure case explicitly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9387e47b-2369-4eca-8f38-e3de47ae0320

📥 Commits

Reviewing files that changed from the base of the PR and between 8d41389 and 0bb89e1.

📒 Files selected for processing (2)
  • src/adaptors/curvance/abi.js
  • src/adaptors/curvance/index.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/adaptors/curvance/abi.js

@llamatester
Copy link

The curvance adapter exports pools:

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

Nb of pools: 34
 

Sample pools:
┌─────────┬────────────────────────────────────────────────────┬─────────┬────────────┬────────────┬────────────────────┬────────────────────┬─────────────────┬──────────────────────────────────────────────────┬────────────────────────────┬───────────────────┬────────────────────┬────────────────────┬────────────┐
│ (index) │ pool                                               │ chain   │ project    │ symbol     │ tvlUsd             │ apyBase            │ poolMeta        │ underlyingTokens                                 │ url                        │ apyBaseBorrow     │ totalSupplyUsd     │ totalBorrowUsd     │ borrowable │
├─────────┼────────────────────────────────────────────────────┼─────────┼────────────┼────────────┼────────────────────┼────────────────────┼─────────────────┼──────────────────────────────────────────────────┼────────────────────────────┼───────────────────┼────────────────────┼────────────────────┼────────────┤
│ 0       │ '0x852ff1ec21d63b405ec431e04ae3ac760e29263d-monad' │ 'Monad' │ 'curvance' │ 'EARNAUSD' │ 17881589.041726846 │ 0                  │ 'earnAUSD/AUSD' │ [ '0x103222f020e98Bba0AD9809A011FDF8e6F067496' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
│ 1       │ '0x7eda3cb060ff7b650eb227971dbfebd3513b11d5-monad' │ 'Monad' │ 'curvance' │ 'SYZUSD'   │ 5801701.719928938  │ 0                  │ 'syzUSD/AUSD'   │ [ '0x484be0540aD49f351eaa04eeB35dF0f937D4E73f' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
│ 2       │ '0xad4aa2a713fb86fbb6b60de2af9e32a11db6abf2-monad' │ 'Monad' │ 'curvance' │ 'AUSD'     │ 3735389.545280748  │ 5.804033375376001  │ 'earnAUSD/AUSD' │ [ '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a' ] │ 'https://app.curvance.com' │ 8.464911874459201 │ 15684506.189601889 │ 11949116.644321142 │ true       │
│ 3       │ '0x20f1a13bfbf85a22aa59d189861790981372220b-monad' │ 'Monad' │ 'curvance' │ 'EZETH'    │ 3090098.067922772  │ 0                  │ 'ezETH/WETH'    │ [ '0x2416092f143378750bb29b79eD961ab195CcEea5' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
│ 4       │ '0x8626b8f4f64caeee9549af8ebbfa591a7425e5ba-monad' │ 'Monad' │ 'curvance' │ 'YZM'      │ 1947713.4253829075 │ 0                  │ 'YZM/AUSD'      │ [ '0x3a2c4aAae6776dC1c31316De559598f2f952E2cB' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
│ 5       │ '0xa206d51c02c0202a2eed8e6a757b49ab13930227-monad' │ 'Monad' │ 'curvance' │ 'WETH'     │ 968534.1151824874  │ 2.6886218441184004 │ 'ezETH/WETH'    │ [ '0xEE8c0E9f1BFFb4Eb878d8f15f368A02a35481242' ] │ 'https://app.curvance.com' │ 4.0738717638432   │ 3631507.021575546  │ 2662972.9063930586 │ true       │
│ 6       │ '0x8e94704607e857eb3e10bd21d90bf8c1ecba0452-monad' │ 'Monad' │ 'curvance' │ 'AUSD'     │ 886586.7052968645  │ 5.7193852609584    │ 'syzUSD/AUSD'   │ [ '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a' ] │ 'https://app.curvance.com' │ 7.5158336649456   │ 5739587.589132693  │ 4853000.883835828  │ true       │
│ 7       │ '0x926c101cf0a3de8725eb24a93e980f9fe34d6230-monad' │ 'Monad' │ 'curvance' │ 'SHMON'    │ 676163.8911535804  │ 0                  │ 'shMON/WMON'    │ [ '0x1B68626dCa36c7fE922fD2d55E4f631d962dE19c' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
│ 8       │ '0x92ee4b4d33dc61bd93a88601f29131b08acedbf1-monad' │ 'Monad' │ 'curvance' │ 'MUBOND'   │ 655154.6942327527  │ 0                  │ 'muBOND/AUSD'   │ [ '0x336D414754967C6682B5A665C7DAF6F1409E63e8' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
│ 9       │ '0xf7a6ab4af86966c141d3c5633df658e5cdb0a735-monad' │ 'Monad' │ 'curvance' │ 'LOAZND'   │ 529647.6963398046  │ 0                  │ 'loAZND/AUSD'   │ [ '0x9c82eB49B51F7Dc61e22Ff347931CA32aDc6cd90' ] │ 'https://app.curvance.com' │                   │                    │                    │            │
└─────────┴────────────────────────────────────────────────────┴─────────┴────────────┴────────────┴────────────────────┴────────────────────┴─────────────────┴──────────────────────────────────────────────────┴────────────────────────────┴───────────────────┴────────────────────┴────────────────────┴────────────┘
This adapter contains some pools with <10k TVL, these pools won't be shown in DefiLlama

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.

2 participants