Skip to content

feat: add velkonix yield adapter (Aave V3 fork on MegaETH)#2768

Open
CryptoBetmen wants to merge 1 commit into
DefiLlama:masterfrom
K613-Official:feat/velkonix-yield-adapter
Open

feat: add velkonix yield adapter (Aave V3 fork on MegaETH)#2768
CryptoBetmen wants to merge 1 commit into
DefiLlama:masterfrom
K613-Official:feat/velkonix-yield-adapter

Conversation

@CryptoBetmen

@CryptoBetmen CryptoBetmen commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features
    • Added support for a new lending protocol, bringing its pool data, rates, TVL, borrow limits, and availability into the app.
    • Displayed pool-level APY and borrowing metrics using live on-chain and price data.
    • Included accurate supply and borrow calculations, with borrow-cap awareness where applicable.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a new yield adaptor for Velkonix at src/adaptors/velkonix/index.js. It fetches reserve and aToken data from a protocol data provider contract on the megaeth chain, computes TVL, borrow, and supply USD values, derives APY and LTV metrics, and exports an apy function with associated metadata.

Changes

Velkonix Adaptor

Layer / File(s) Summary
On-chain data fetching setup
src/adaptors/velkonix/index.js
Defines chain and protocol constants, then queries reserve/aToken lists, reserve data, configuration, borrow caps, underlying balances, token decimals, and prices via multis calls and price API.
Pool computation and export
src/adaptors/velkonix/index.js
Transforms fetched data into pool objects with TVL, borrow/supply USD, APY, and LTV fields, filters invalid entries with utils.keepFinite, and exports the adaptor with apy, timetravel, url, and protocolId.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A new burrow opens, Velkonix in sight,
Reserves and aTokens hopping into light,
Prices fetched, decimals aligned just right,
TVL and borrow caps computed tonight,
Hop along, reviewer—this pool's looking bright! 🐇🥕

🚥 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 matches the change: it adds a Velkonix yield adapter and correctly notes the MegaETH/Aave V3 fork context.
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

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

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

Nb of pools: 6
 

Sample pools:
┌─────────┬──────────────────────────────────────────────────────┬───────────┬────────────┬──────────┬────────────────────┬─────────────────────┬──────────────────────────────────────────────────┬────────────────────┬────────────────────┬────────────────────┬────────────────────┬──────────────────────────────────────────────┬──────┬────────────┬──────────────────────────────────────────────┐
│ (index) │ pool                                                 │ chain     │ project    │ symbol   │ tvlUsd             │ apyBase             │ underlyingTokens                                 │ totalSupplyUsd     │ totalBorrowUsd     │ availableBorrowUsd │ apyBaseBorrow      │ borrowToken                                  │ ltv  │ borrowable │ token                                        │
├─────────┼──────────────────────────────────────────────────────┼───────────┼────────────┼──────────┼────────────────────┼─────────────────────┼──────────────────────────────────────────────────┼────────────────────┼────────────────────┼────────────────────┼────────────────────┼──────────────────────────────────────────────┼──────┼────────────┼──────────────────────────────────────────────┤
│ 0       │ '0x0ce2adeb7150225e5f716e9fe1a3042137bef7c4-megaeth' │ 'MegaETH' │ 'velkonix' │ 'USDm'   │ 89.942372098261    │ 0.10833333333333332 │ [ '0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7' ] │ 99.9405783879744   │ 9.998206289713389  │ 89.942372098261    │ 1.4444444444444444 │ '0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7' │ 0.8  │ true       │ '0x0cE2adEb7150225E5F716E9fE1A3042137bEF7C4' │
│ 1       │ '0x5a139ceb29abaa515342f19bd72c60731d7e4741-megaeth' │ 'MegaETH' │ 'velkonix' │ 'USDe'   │ 49.422615383631005 │ 0.4915495371605058  │ [ '0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34' ] │ 69.39433554815292  │ 19.97172016452192  │ 49.422615383631005 │ 2.278450490212289  │ '0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34' │ 0.8  │ true       │ '0x5a139CeB29Abaa515342f19bD72c60731d7e4741' │
│ 2       │ '0x126d6703c1f4990e58570c55bea47c825676bdf1-megaeth' │ 'MegaETH' │ 'velkonix' │ 'USDT0'  │ 5.876240359147074  │ 1.2083333333333333  │ [ '0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb' ] │ 11.758528538209895 │ 5.8822881790628205 │ 5.876240359147074  │ 3.222222222222222  │ '0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb' │ 0.8  │ true       │ '0x126d6703c1f4990E58570C55Bea47c825676BDf1' │
│ 3       │ '0x6d0dc971443380d3d51a19b1da9d6bd80a9d5640-megaeth' │ 'MegaETH' │ 'velkonix' │ 'wstETH' │ 4.460706117114675  │ 1.1953161671621855  │ [ '0x601aC63637933D88285A025C685AC4e9a92a98dA' ] │ 8.925969351346343  │ 4.465263234231666  │ 4.460706117114675  │ 3.1875039798629907 │ '0x601aC63637933D88285A025C685AC4e9a92a98dA' │ 0.75 │ true       │ '0x6D0dc971443380d3d51A19b1Da9d6bd80a9d5640' │
│ 4       │ '0x78ee31fb826f23901c0bf770c3f36576938a60fa-megaeth' │ 'MegaETH' │ 'velkonix' │ 'WETH'   │ 4.448401891152602  │ 1.1953123964508865  │ [ '0x4200000000000000000000000000000000000006' ] │ 8.901331901414524  │ 4.452930010261922  │ 4.448401891152602  │ 3.1874998876211147 │ '0x4200000000000000000000000000000000000006' │ 0.78 │ true       │ '0x78ee31fB826F23901C0bf770C3f36576938A60Fa' │
│ 5       │ '0xdc8855dec1eb38610b27764982354f3f1f3452d0-megaeth' │ 'MegaETH' │ 'velkonix' │ 'BTC.b'  │ 3.048101396146932  │ 1.9120953619040604  │ [ '0xB0F70C0bD6FD87dbEb7C10dC692a2a6106817072' ] │ 8.90897928710585   │ 5.860877890958918  │ 3.048101396146932  │ 3.8769645557966723 │ '0xB0F70C0bD6FD87dbEb7C10dC692a2a6106817072' │ 0.68 │ true       │ '0xDC8855DEC1Eb38610B27764982354F3f1f3452d0' │
└─────────┴──────────────────────────────────────────────────────┴───────────┴────────────┴──────────┴────────────────────┴─────────────────────┴──────────────────────────────────────────────────┴────────────────────┴────────────────────┴────────────────────┴────────────────────┴──────────────────────────────────────────────┴──────┴────────────┴──────────────────────────────────────────────┘
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/velkonix/index.js (1)

72-80: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Scale underlying amounts with underlying token decimals.

Line 77 fetches decimals from the aToken, but Lines 101-104 scale underlying balances/debts. Aave aTokens usually mirror underlying decimals, but using reserveTokens avoids silent mis-scaling if this fork diverges.

Proposed change
-  const underlyingDecimals = (
+  const underlyingDecimals = (
     await sdk.api.abi.multiCall({
       chain: CHAIN,
       abi: 'erc20:decimals',
-      calls: aTokens.map((t) => ({
-        target: t.tokenAddress,
+      calls: reserveTokens.map((t) => ({
+        target: t.tokenAddress,
       })),
     })
   ).output.map((o) => o.output);
🤖 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/velkonix/index.js` around lines 72 - 80, The underlying amount
scaling in the Velkonix adapter is using decimals fetched from the aToken, which
can silently mis-scale balances if the fork’s aToken decimals differ from the
underlying asset. Update the decimal lookup in the aToken processing flow to use
the reserve/underlying token entries from the existing token data, and make sure
the scaling applied later to underlying balances and debts uses those underlying
token decimals consistently in the Velkonix index logic.
🤖 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/velkonix/index.js`:
- Around line 101-111: The liquidity calculation in the Velkonix adaptor is
using idle cash for tvlUsd, which underreports TVL once borrowing exists. In the
pricing loop in index.js, update the tvlUsd assignment to use total supplied
liquidity (the existing totalSupplyUsd derived from underlying balances plus
total borrow) and keep the idle/capped liquidity logic only for
availableBorrowUsd. Make the same adjustment anywhere else the same pattern
appears, including the later block referenced in the review, so tvlUsd
consistently represents supplied liquidity rather than available cash.

---

Nitpick comments:
In `@src/adaptors/velkonix/index.js`:
- Around line 72-80: The underlying amount scaling in the Velkonix adapter is
using decimals fetched from the aToken, which can silently mis-scale balances if
the fork’s aToken decimals differ from the underlying asset. Update the decimal
lookup in the aToken processing flow to use the reserve/underlying token entries
from the existing token data, and make sure the scaling applied later to
underlying balances and debts uses those underlying token decimals consistently
in the Velkonix index logic.
🪄 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: 8e1a1ee1-46cb-479e-9f19-8ef994eed3ad

📥 Commits

Reviewing files that changed from the base of the PR and between c4c41d0 and 9f04ac9.

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

Comment on lines +101 to +111
const tvlUsd = toTokenAmount(underlyingBalances[i]) * price;
const totalBorrow =
BigInt(p.totalStableDebt) + BigInt(p.totalVariableDebt);
const totalBorrowUsd = toTokenAmount(totalBorrow) * price;
const totalSupplyUsd = tvlUsd + totalBorrowUsd;

const borrowCap = Number(poolsReserveCaps[i].borrowCap);
const borrowCapUsd = borrowCap * price;
const availableBorrowUsd = borrowCap
? Math.max(Math.min(tvlUsd, borrowCapUsd - totalBorrowUsd), 0)
: 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.

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

Report supplied liquidity as tvlUsd, not only idle liquidity.

Line 101 currently makes tvlUsd equal the underlying cash sitting in the aToken contract. Once users borrow, that underreports pool TVL by the borrowed amount. Keep available liquidity separate for availableBorrowUsd, and set tvlUsd from total supplied liquidity.

Proposed change
-      const tvlUsd = toTokenAmount(underlyingBalances[i]) * price;
+      const availableLiquidityUsd =
+        toTokenAmount(underlyingBalances[i]) * price;
       const totalBorrow =
         BigInt(p.totalStableDebt) + BigInt(p.totalVariableDebt);
       const totalBorrowUsd = toTokenAmount(totalBorrow) * price;
-      const totalSupplyUsd = tvlUsd + totalBorrowUsd;
+      const totalSupplyUsd = availableLiquidityUsd + totalBorrowUsd;
+      const tvlUsd = totalSupplyUsd;
 
       const borrowCap = Number(poolsReserveCaps[i].borrowCap);
       const borrowCapUsd = borrowCap * price;
       const availableBorrowUsd = borrowCap
-        ? Math.max(Math.min(tvlUsd, borrowCapUsd - totalBorrowUsd), 0)
-        : tvlUsd;
+        ? Math.max(
+            Math.min(availableLiquidityUsd, borrowCapUsd - totalBorrowUsd),
+            0
+          )
+        : availableLiquidityUsd;

Also applies to: 118-123

🤖 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/velkonix/index.js` around lines 101 - 111, The liquidity
calculation in the Velkonix adaptor is using idle cash for tvlUsd, which
underreports TVL once borrowing exists. In the pricing loop in index.js, update
the tvlUsd assignment to use total supplied liquidity (the existing
totalSupplyUsd derived from underlying balances plus total borrow) and keep the
idle/capped liquidity logic only for availableBorrowUsd. Make the same
adjustment anywhere else the same pattern appears, including the later block
referenced in the review, so tvlUsd consistently represents supplied liquidity
rather than available cash.

@0xkr3p

0xkr3p commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

hi @CryptoBetmen, thanks for your PR - the TVL of these pools is extremely small and does not meet the 10k threshold to be displayed on defillama. Pls ping me when a pool is around this level and I will recheck.

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