feat: add kerne protocol yield adapter#2254
feat: add kerne protocol yield adapter#2254enerzy17 wants to merge 2 commits intoDefiLlama:masterfrom
Conversation
|
@enerzy17 make sure we have a tvl adapter first, otherwise we can't list on yields. also pls check the test output |
📝 WalkthroughWalkthroughAdds 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
Sequence DiagramsequenceDiagram
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, ...}]
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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.
| // Kerne Protocol Yield Adapter for DefiLlama | ||
| // VAULT_ADDRESS: 0x5FD0F7eA40984a6a8E9c6f6BDfd297e7dB4448Bd | ||
| // ASSET: WETH (0x4200000000000000000000000000000000000006) | ||
|
|
||
| const VAULT_ADDRESS = "0xDF9a2f5152c533F7fcc3bAdEd41e157C9563C695"; | ||
| const WETH_ADDRESS = "0x4200000000000000000000000000000000000006"; |
There was a problem hiding this comment.
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.
| // 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.
| 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" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's check if the file exists and examine its structure
find . -name "index.js" -path "*/kerne-protocol/*" | head -5Repository: 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 -50Repository: DefiLlama/yield-server
Length of output: 2444
🏁 Script executed:
# Check how other adaptors handle external API calls
find . -name "index.js" -path "*/adaptors/*" | head -10Repository: 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.jsRepository: 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 -40Repository: 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 1Repository: 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 -60Repository: 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 -50Repository: 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 -10Repository: 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 -40Repository: 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 -40Repository: 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 -20Repository: 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.
Summary by CodeRabbit
Release Notes