Skip to content

feat: add kerne protocol yield adapter#2254

Closed
enerzy17 wants to merge 2 commits intoDefiLlama:masterfrom
kerne-protocol:master
Closed

feat: add kerne protocol yield adapter#2254
enerzy17 wants to merge 2 commits intoDefiLlama:masterfrom
kerne-protocol:master

Conversation

@enerzy17
Copy link
Copy Markdown

@enerzy17 enerzy17 commented Jan 6, 2026

Summary by CodeRabbit

Release Notes

  • New Features
    • Added Kerne Protocol Yield Adapter with live APY and TVL data fetching for the Base chain vault, displaying real-time yield metrics on kLP tokens from Kerne Finance.

@slasher125
Copy link
Copy Markdown
Collaborator

@enerzy17 make sure we have a tvl adapter first, otherwise we can't list on yields. also pls check the test output

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 3, 2026

📝 Walkthrough

Walkthrough

Adds a new Kerne Protocol Yield Adapter for DefiLlama that fetches APY data via HTTP from the Kerne Finance API and returns a single pool entry containing TVL, APY, underlying tokens, and metadata for the Base chain vault.

Changes

Cohort / File(s) Summary
Kerne Protocol Adapter
src/adaptors/kerne-protocol/index.js
New adapter file introducing APY data fetching from Kerne Finance API, pool construction with vault details on Base chain, and module exports for DefiLlama integration.

Sequence Diagram

sequenceDiagram
    participant DL as DefiLlama
    participant Adapter as Kerne Adapter
    participant API as Kerne API<br/>(kerne.finance)
    participant Data as Pool Data

    DL->>Adapter: Call apy()
    Adapter->>API: GET /api/stats
    API-->>Adapter: {tvl_usd, current_apy}
    Adapter->>Data: Construct pool object<br/>(VAULT_ADDRESS-base, Base, kLP)
    Adapter->>Data: Assign tvlUsd, apyBase<br/>from response
    Data-->>Adapter: Pool entry ready
    Adapter-->>DL: Return [{pool, chain,<br/>project, symbol, tvlUsd,<br/>apyBase, ...}]
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A new adapter hops into place,
Kerne's data flows with grace,
Base chain vaults now on the map,
APY stats close the gap,
DefiLlama grows, no need to race! 🌱

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add kerne protocol yield adapter' clearly and concisely describes the main change—adding a new yield adapter for the Kerne Protocol, which aligns perfectly with the changeset.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Copy link
Copy Markdown
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

🤖 Fix all issues with AI agents
In `@src/adaptors/kerne-protocol/index.js`:
- Around line 3-8: Header comment's VAULT_ADDRESS (in the top block) is
inconsistent with the VAULT_ADDRESS constant; update the comment to match the
constant value "0xDF9a2f5152c533F7fcc3bAdEd41e157C9563C695". Edit the header
comment line that currently lists "VAULT_ADDRESS:
0x5FD0F7eA40984a6a8E9c6f6BDfd297e7dB4448Bd" so it shows the same address as the
VAULT_ADDRESS constant to avoid confusion when inspecting VAULT_ADDRESS and
WETH_ADDRESS in this module.
- Around line 10-26: In the apy function, add a timeout option to the axios.get
call (so the request to "https://kerne.finance/api/stats" cannot hang) and
validate numeric fields after parsing (tvl_usd and current_apy) before
returning: call parseFloat on data.tvl_usd and data.current_apy, check for
Number.isFinite on the results and throw a clear error if they are invalid/NaN
so upstream sees the failure; keep VAULT_ADDRESS and WETH_ADDRESS usage and the
returned object shape unchanged, but ensure the axios request includes a timeout
and validation happens immediately after response.data is assigned.

Comment on lines +3 to +8
// Kerne Protocol Yield Adapter for DefiLlama
// VAULT_ADDRESS: 0x5FD0F7eA40984a6a8E9c6f6BDfd297e7dB4448Bd
// ASSET: WETH (0x4200000000000000000000000000000000000006)

const VAULT_ADDRESS = "0xDF9a2f5152c533F7fcc3bAdEd41e157C9563C695";
const WETH_ADDRESS = "0x4200000000000000000000000000000000000006";
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.

⚠️ Potential issue | 🟡 Minor

Update the VAULT_ADDRESS comment to match the constant.

The header comment lists a different address than the value used at Line 7, which can mislead maintainers.

🧩 Suggested fix
-// VAULT_ADDRESS: 0x5FD0F7eA40984a6a8E9c6f6BDfd297e7dB4448Bd
+// VAULT_ADDRESS: 0xDF9a2f5152c533F7fcc3bAdEd41e157C9563C695
📝 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
// Kerne Protocol Yield Adapter for DefiLlama
// VAULT_ADDRESS: 0x5FD0F7eA40984a6a8E9c6f6BDfd297e7dB4448Bd
// ASSET: WETH (0x4200000000000000000000000000000000000006)
const VAULT_ADDRESS = "0xDF9a2f5152c533F7fcc3bAdEd41e157C9563C695";
const WETH_ADDRESS = "0x4200000000000000000000000000000000000006";
// Kerne Protocol Yield Adapter for DefiLlama
// VAULT_ADDRESS: 0xDF9a2f5152c533F7fcc3bAdEd41e157C9563C695
// ASSET: WETH (0x4200000000000000000000000000000000000006)
const VAULT_ADDRESS = "0xDF9a2f5152c533F7fcc3bAdEd41e157C9563C695";
const WETH_ADDRESS = "0x4200000000000000000000000000000000000006";
🤖 Prompt for AI Agents
In `@src/adaptors/kerne-protocol/index.js` around lines 3 - 8, Header comment's
VAULT_ADDRESS (in the top block) is inconsistent with the VAULT_ADDRESS
constant; update the comment to match the constant value
"0xDF9a2f5152c533F7fcc3bAdEd41e157C9563C695". Edit the header comment line that
currently lists "VAULT_ADDRESS: 0x5FD0F7eA40984a6a8E9c6f6BDfd297e7dB4448Bd" so
it shows the same address as the VAULT_ADDRESS constant to avoid confusion when
inspecting VAULT_ADDRESS and WETH_ADDRESS in this module.

Comment on lines +10 to +26
async function apy() {
// This function is used by DefiLlama Yields to track APY over time
// It pulls from our public stats API which reflects the bot's actual performance
const response = await axios.get("https://kerne.finance/api/stats");
const data = response.data;

return [
{
pool: `${VAULT_ADDRESS}-base`,
chain: "Base",
project: "kerne-protocol",
symbol: "kLP",
tvlUsd: parseFloat(data.tvl_usd),
apyBase: parseFloat(data.current_apy),
underlyingTokens: [WETH_ADDRESS],
rewardTokens: [], // Kerne yield is auto-compounding in kLP price
url: "https://kerne.finance/terminal"
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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's check if the file exists and examine its structure
find . -name "index.js" -path "*/kerne-protocol/*" | head -5

Repository: DefiLlama/yield-server

Length of output: 104


🏁 Script executed:

# Check the actual content of the file around lines 10-26
cat -n src/adaptors/kerne-protocol/index.js | sed -n '1,35p'

Repository: DefiLlama/yield-server

Length of output: 1399


🏁 Script executed:

# Search for axios configuration in the codebase to see if there's a default timeout
rg "axios" -t js -A 3 -B 1 | head -50

Repository: DefiLlama/yield-server

Length of output: 2444


🏁 Script executed:

# Check how other adaptors handle external API calls
find . -name "index.js" -path "*/adaptors/*" | head -10

Repository: DefiLlama/yield-server

Length of output: 409


🏁 Script executed:

# Check a few other adaptors to see error handling patterns
head -40 ./src/adaptors/aave-v2/index.js

Repository: DefiLlama/yield-server

Length of output: 1313


🏁 Script executed:

# Search for error handling patterns around axios.get calls
rg "axios\.get" -A 5 src/adaptors/ | grep -A 5 "try\|catch\|timeout\|error" | head -40

Repository: DefiLlama/yield-server

Length of output: 2026


🏁 Script executed:

# Check if there are any error handlers or wrappers at the module level
rg "try.*catch|async.*apy|module.exports" src/adaptors/kerne-protocol/ -A 3 -B 1

Repository: DefiLlama/yield-server

Length of output: 772


🏁 Script executed:

# Search for how numeric field validation is done elsewhere in adaptors
rg "parseFloat|Number\(" src/adaptors/ -B 2 -A 2 | head -60

Repository: DefiLlama/yield-server

Length of output: 3771


🏁 Script executed:

# Find where apy functions are called/invoked
rg "\.apy\(|apy\(\)" src/ -B 3 -A 3 | head -50

Repository: DefiLlama/yield-server

Length of output: 3091


🏁 Script executed:

# Check if there's a main entry point or orchestration that wraps these calls
find . -name "*.js" -path "*/src/*" -not -path "*/adaptors/*" | head -10

Repository: DefiLlama/yield-server

Length of output: 343


🏁 Script executed:

# Look for how module.exports with apy is consumed
rg "module\.exports.*apy|require.*adaptors" src/ -B 2 -A 2 | head -40

Repository: DefiLlama/yield-server

Length of output: 1890


🏁 Script executed:

# Check the error handling in triggerAdaptor.js around the apy() call
cat -n src/handlers/triggerAdaptor.js | sed -n '1,60p'

Repository: DefiLlama/yield-server

Length of output: 2239


🏁 Script executed:

# Look for try-catch or error handling around the apy call
cat -n src/handlers/triggerAdaptor.js | grep -A 20 "project.apy()"

Repository: DefiLlama/yield-server

Length of output: 1117


🏁 Script executed:

# Check if there's validation logic elsewhere
rg "Number\.isFinite|NaN|isNaN" src/ -B 2 -A 2 | head -40

Repository: DefiLlama/yield-server

Length of output: 2446


🏁 Script executed:

# Get more context around the NaN nullification to understand the full picture
cat -n src/handlers/triggerAdaptor.js | sed -n '45,90p'

Repository: DefiLlama/yield-server

Length of output: 2229


🏁 Script executed:

# Check if axios has any default timeout in the repository
rg "axios\.create|axios\.defaults|timeout" -t js | grep -v node_modules | head -20

Repository: DefiLlama/yield-server

Length of output: 1707


Add a timeout and validate numeric fields before returning.

The external API call lacks a timeout and can hang indefinitely. Additionally, parseFloat on missing or invalid fields returns NaN, which silently propagates through the pipeline. While downstream code does null out invalid values, it's better to validate at the source and throw an error for visibility.

🛠️ Proposed fix
 async function apy() {
   // This function is used by DefiLlama Yields to track APY over time
   // It pulls from our public stats API which reflects the bot's actual performance
-  const response = await axios.get("https://kerne.finance/api/stats");
-  const data = response.data;
+  const response = await axios.get("https://kerne.finance/api/stats", {
+    timeout: 10_000,
+  });
+  const data = response.data;
+  const tvlUsd = Number(data?.tvl_usd);
+  const apyBase = Number(data?.current_apy);
+  if (!Number.isFinite(tvlUsd) || !Number.isFinite(apyBase)) {
+    throw new Error("Invalid stats payload: tvl_usd/current_apy");
+  }
   
   return [
     {
       pool: `${VAULT_ADDRESS}-base`,
       chain: "Base",
       project: "kerne-protocol",
       symbol: "kLP",
-      tvlUsd: parseFloat(data.tvl_usd),
-      apyBase: parseFloat(data.current_apy),
+      tvlUsd,
+      apyBase,
       underlyingTokens: [WETH_ADDRESS],
       rewardTokens: [], // Kerne yield is auto-compounding in kLP price
       url: "https://kerne.finance/terminal"
     }
   ];
 }
🤖 Prompt for AI Agents
In `@src/adaptors/kerne-protocol/index.js` around lines 10 - 26, In the apy
function, add a timeout option to the axios.get call (so the request to
"https://kerne.finance/api/stats" cannot hang) and validate numeric fields after
parsing (tvl_usd and current_apy) before returning: call parseFloat on
data.tvl_usd and data.current_apy, check for Number.isFinite on the results and
throw a clear error if they are invalid/NaN so upstream sees the failure; keep
VAULT_ADDRESS and WETH_ADDRESS usage and the returned object shape unchanged,
but ensure the axios request includes a timeout and validation happens
immediately after response.data is assigned.

@slasher125 slasher125 closed this Feb 24, 2026
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