Skip to content

feat: add DorkFi yield adapter (Algorand + Voi Network)#2787

Open
mikepappalardo wants to merge 2 commits into
DefiLlama:masterfrom
mikepappalardo:feat/dorkfi
Open

feat: add DorkFi yield adapter (Algorand + Voi Network)#2787
mikepappalardo wants to merge 2 commits into
DefiLlama:masterfrom
mikepappalardo:feat/dorkfi

Conversation

@mikepappalardo

@mikepappalardo mikepappalardo commented Jul 8, 2026

Copy link
Copy Markdown

Adds the DorkFi yield adapter for Algorand and Voi Network.

This supersedes closed PR #2599. That PR was closed as stale while review comments were unresolved, and GitHub would not allow it to be reopened after the branch update.

Updates included here:

  • Adds underlyingTokens for every DorkFi pool using the on-chain market asset ID as a string.
  • Uses on-chain IDs for UNIT and WAD because they are not listed on CoinGecko yet.
  • Adds 30s axios request timeouts.
  • Handles per-chain market/TVL fetch failures gracefully.
  • Detects missing TVL entries explicitly instead of silently treating them as dust.

Validated locally:

npm run test --adapter=dorkfi

Result: 1 test suite passed, 376 tests passed.

Summary by CodeRabbit

  • New Features
    • Added support for viewing DorkFi lending market data and TVL on Algorand and Voi.
    • Added supply and borrow APY estimates for supported markets.
    • Included market symbols, token details, and pool links in returned market data.

Reports supply and borrow APY for all 47 DorkFi lending markets across
two chains and four pools.

Pools:
  Algorand: 3333688282 (Pool A), 3345940978 (Pool B)
  Voi:      47139778   (Pool A), 47139781   (Pool B)

APY computed from the protocol's kinked utilization curve:
  borrow APY = borrowRate + utilization × slope
  supply APY = borrow APY × utilization × (1 − reserveFactor)

Markets include ALGO, USDC, goBTC, goETH, WBTC, WETH, LINK, SOL,
USDT, VOI, UNIT, WAD, aUSDC, POW, tALGO, FINITE, FOLKS, COOP, GOLD$ and more.

Data sourced from DorkFi API (dorkfi-api.nautilus.sh).
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new DefiLlama yield-server adapter for DorkFi (src/adaptors/dorkfi/index.js) that fetches lending market data and TVL for Algorand and Voi chains, computes supply/borrow APYs from kinked utilization curve parameters, and exports apy, timeTravel, and url.

Changes

DorkFi Adapter

Layer / File(s) Summary
Market metadata and symbol mapping
src/adaptors/dorkfi/index.js
Defines chain-specific API endpoints and a MARKET_SYMBOLS map resolving marketId to token symbols, with an ASA-based fallback.
Data fetching and deduplication
src/adaptors/dorkfi/index.js
Adds fetchMarketData and fetchAnalyticsTVL async helpers using axios with timeouts and warning/empty fallbacks, plus a dedup function keeping the latest record per appId:marketId.
APY computation utilities
src/adaptors/dorkfi/index.js
Adds bpsToApy (compounding conversion), computeRates (utilization, borrowBps, supplyBps derivation), and getUnderlyingTokens helpers.
Main adapter flow and exports
src/adaptors/dorkfi/index.js
Implements apy() to fetch markets/TVL concurrently per chain, filter by TVL threshold, compute APYs, build pool objects, and exports apy, timeTravel: false, and url.

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

Sequence Diagram(s)

sequenceDiagram
  participant apy as apy()
  participant fetchMarketData
  participant fetchAnalyticsTVL
  participant computeRates
  apy->>fetchMarketData: request market data per chain
  apy->>fetchAnalyticsTVL: request TVL per chain
  fetchMarketData-->>apy: markets or empty fallback
  fetchAnalyticsTVL-->>apy: tvl data or empty fallback
  apy->>apy: dedup markets by appId:marketId
  apy->>computeRates: pass market params
  computeRates-->>apy: supply/borrow APY
  apy->>apy: filter by tvlUsd >= 1
  apy-->>apy: build pool objects
Loading

Suggested reviewers: 0xkr3p

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a DorkFi yield adapter for Algorand and Voi Network.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 unit tests (beta)
  • Create PR with unit tests

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 failed: one or more packages not found in the registry.


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

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

The abracadabra-spell adapter exports pools:

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

Nb of pools: 2
 

Sample pools:
┌─────────┬──────────────────────────────────────────────────────────┬────────────┬─────────────────────┬────────────────────┬───────────────────┬───────────────────┬──────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────┬────────────────────────────────────────────────┐
│ (index) │ pool                                                     │ chain      │ project             │ tvlUsd             │ symbol            │ apyReward         │ rewardTokens                                     │ underlyingTokens                                                                                                                             │ apyBase │ url                                            │
├─────────┼──────────────────────────────────────────────────────────┼────────────┼─────────────────────┼────────────────────┼───────────────────┼───────────────────┼──────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────┼────────────────────────────────────────────────┤
│ 0       │ '0xb5de0c3753b6e1b4dba616db82767f17513e6d4e-abracadabra' │ 'Ethereum' │ 'abracadabra-spell' │ 142180.95030432282 │ 'SPELL-WETH'      │ 18.16085955693307 │ [ '0x090185f2135308bad17527004364ebcc2d37e5f6' ] │ [ '0x090185f2135308BaD17527004364eBcC2D37e5F6', '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' ]                                               │         │                                                │
│ 1       │ '0x6d2070b13929df15b13d96cfc509c574168988cd-arbitrum'    │ 'Arbitrum' │ 'abracadabra-spell' │ 4775.612033589783  │ 'MIM-USDC.e-USDT' │ 0                 │ []                                               │ [ '0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A', '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9' ] │ 0       │ 'https://app.abracadabra.money/#/farm/4/42161' │
└─────────┴──────────────────────────────────────────────────────────┴────────────┴─────────────────────┴────────────────────┴───────────────────┴───────────────────┴──────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴─────────┴────────────────────────────────────────────────┘
This adapter contains some pools with <10k TVL, these pools won't be shown in DefiLlama

@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

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

177-188: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider populating totalSupplyUsd and totalBorrowUsd.

The Pool interface defines optional totalSupplyUsd and totalBorrowUsd fields for lending protocols. The adapter already has totalScaledDeposits and totalScaledBorrows from the market data. Populating these fields would improve data quality for downstream consumers and DefiLlama's lending protocol dashboards.

♻️ Suggested addition
       const { borrowApy, supplyApy } = computeRates(market);
       const symbol = MARKET_SYMBOLS[market.marketId] || `ASA-${market.marketId}`;
 
       results.push({
         pool:          `dorkfi-${chain}-${market.appId}-${market.marketId}`,
         chain:         DL_CHAIN[chain],
         project:       PROJECT,
         symbol,
         tvlUsd,
         apyBase:       supplyApy,
         apyBaseBorrow: borrowApy,
+        totalSupplyUsd: Number(market.totalScaledDeposits || 0),
+        totalBorrowUsd: Number(market.totalScaledBorrows || 0),
         underlyingTokens: getUnderlyingTokens(market),
         poolMeta:      `Pool ${market.appId}`,
         url:           'https://dork.fi',
       });
🤖 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/dorkfi/index.js` around lines 177 - 188, Populate the lending
pool supply/borrow totals in the DorkFi adapter result object. In
`src/adaptors/dorkfi/index.js`, update the object pushed in the main market
mapping so it also sets `totalSupplyUsd` and `totalBorrowUsd` using the existing
market data fields (`totalScaledDeposits` and `totalScaledBorrows`) alongside
`tvlUsd`, `apyBase`, and `apyBaseBorrow`. Keep the change localized to the pool
construction logic so the `results.push` payload includes these optional `Pool`
fields.
🤖 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/dorkfi/index.js`:
- Around line 171-172: The `tvlUsd` value in `src/adaptors/dorkfi/index.js` is
taken directly from `tvlMap[key]` and may be a string, which can break the
numeric boundary checks later in `triggerAdaptor.js`. Update the `tvlUsd`
assignment in this adaptor to explicitly convert the API value to a number
before the `if (tvlUsd < 1) continue` filter, using the same numeric handling
pattern already used for other fields so downstream comparisons stay consistent.

---

Nitpick comments:
In `@src/adaptors/dorkfi/index.js`:
- Around line 177-188: Populate the lending pool supply/borrow totals in the
DorkFi adapter result object. In `src/adaptors/dorkfi/index.js`, update the
object pushed in the main market mapping so it also sets `totalSupplyUsd` and
`totalBorrowUsd` using the existing market data fields (`totalScaledDeposits`
and `totalScaledBorrows`) alongside `tvlUsd`, `apyBase`, and `apyBaseBorrow`.
Keep the change localized to the pool construction logic so the `results.push`
payload includes these optional `Pool` fields.
🪄 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: ec5205a5-a04c-405a-b3cb-8221837ba834

📥 Commits

Reviewing files that changed from the base of the PR and between 1329169 and 6255089.

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

Comment on lines +171 to +172
const tvlUsd = tvlMap[key] || 0;
if (tvlUsd < 1) continue;

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.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Ensure tvlUsd is a numeric type.

tvlMap[key] comes directly from the API response without explicit Number() conversion. If the API returns a string, the downstream tvlUsd boundary filter in triggerAdaptor.js performs comparisons without casting tvlUsd (only APY fields are cast), which could lead to incorrect filtering.

🛡️ Proposed fix
-      const tvlUsd = tvlMap[key] || 0;
+      const tvlUsd = Number(tvlMap[key]) || 0;
       if (tvlUsd < 1) continue;
📝 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
const tvlUsd = tvlMap[key] || 0;
if (tvlUsd < 1) continue;
const tvlUsd = Number(tvlMap[key]) || 0;
if (tvlUsd < 1) continue;
🤖 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/dorkfi/index.js` around lines 171 - 172, The `tvlUsd` value in
`src/adaptors/dorkfi/index.js` is taken directly from `tvlMap[key]` and may be a
string, which can break the numeric boundary checks later in
`triggerAdaptor.js`. Update the `tvlUsd` assignment in this adaptor to
explicitly convert the API value to a number before the `if (tvlUsd < 1)
continue` filter, using the same numeric handling pattern already used for other
fields so downstream comparisons stay consistent.

return results;
};

module.exports = { apy, timeTravel: false, url: 'https://dork.fi' };

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.

pls add protocolId: 7531

timeTravel should be all lowercase

symbol,
tvlUsd,
apyBase: supplyApy,
apyBaseBorrow: borrowApy,

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.

missing these fields:
ltv, totalSupplyUsd, totalBorrowUsd

chain: DL_CHAIN[chain],
project: PROJECT,
symbol,
tvlUsd,

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.

just checking tvlUsd should be available liquidity, e.g. deposits - borrows

@0xkr3p 0xkr3p 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.

hi @mikepappalardo, thanks for the PR. A few things to resolve before we can move forwards. I don't think these underlying tokens will resolve we should use coingecko ids where possible particualrly for the popular tokens for example: coingecko:voi-network, coingecko:aave-v3-usdc


for (const market of dedup(markets)) {
const key = `${market.appId}:${market.marketId}`;
const hasTvl = Object.prototype.hasOwnProperty.call(tvlMap, key);

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.

can we skip 'paused' markets?

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