feat: update rewards apy#2316
Conversation
📝 WalkthroughWalkthroughUpdated YO protocol adaptor: import formatting and MERKL_API_URL creatorAddress changed, added Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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 |
|
The yo-protocol adapter exports pools: Test Suites: 1 passed, 1 total |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/adaptors/yo-protocol/index.js`:
- Around line 81-82: Remove the debug console.log in
src/adaptors/yo-protocol/index.js (the line "console.log('result', result);") so
it doesn't pollute production logs; if the result needs to be recorded, replace
it with the appropriate logger call (e.g., use the module's logger or
processLogger) at the relevant function scope where "result" is produced.
|
The yo-protocol adapter exports pools: Test Suites: 1 passed, 1 total |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/adaptors/yo-protocol/index.js`:
- Around line 9-15: The adaptor currently treats all vaults as Base which breaks
yoGOLD on Ethereum; update pricing and links to be chain-aware by grouping
vaults by vault.chain.name (use .toLowerCase()), calling getPrices per chain
(pass chain into getPrices) and merging the returned prices into a single
pricesByAddress lookup used when computing tvlUsd, and construct vault URLs
using the chain in the path (e.g., `vault.chain.name.toLowerCase()` plus
`vault.contracts.vaultAddress`); ensure references to symboToNameMap remain
intact and that tvlUsd calculation and the URL property use the chain-specific
price/address data.
| const symboToNameMap = { | ||
| yoETH: 'Yield Optimizer ETH', | ||
| yoBTC: 'Yield Optimizer BTC', | ||
| yoUSD: 'Yield Optimizer USD', | ||
| yoEUR: 'Yield Optimizer EUR', | ||
| yoGOLD: 'Yield Optimizer GOLD', | ||
| }; |
There was a problem hiding this comment.
Make pricing and URLs chain-aware for yoGOLD (Ethereum).
Adding yoGOLD implies non‑Base vaults; the adaptor still hardcodes Base in pricing and URLs, so tvlUsd and links will be wrong for Ethereum vaults. Consider grouping by vault.chain.name for pricing and using the chain in the URL path (lowercased).
Example approach (multi-chain pricing + chain-aware URLs)
const vaultsByChain = vaults.reduce((acc, v) => {
const chain = v.chain.name.toLowerCase();
(acc[chain] ??= []).push(v);
return acc;
}, {});
const pricesByAddress = {};
for (const [chain, vs] of Object.entries(vaultsByChain)) {
const prices = await getPrices(vs.map(v => v.asset.address), chain);
Object.assign(pricesByAddress, prices.pricesByAddress);
}
// ...
url: `https://app.yo.xyz/vault/${vault.chain.name.toLowerCase()}/${vault.contracts.vaultAddress}`,🤖 Prompt for AI Agents
In `@src/adaptors/yo-protocol/index.js` around lines 9 - 15, The adaptor currently
treats all vaults as Base which breaks yoGOLD on Ethereum; update pricing and
links to be chain-aware by grouping vaults by vault.chain.name (use
.toLowerCase()), calling getPrices per chain (pass chain into getPrices) and
merging the returned prices into a single pricesByAddress lookup used when
computing tvlUsd, and construct vault URLs using the chain in the path (e.g.,
`vault.chain.name.toLowerCase()` plus `vault.contracts.vaultAddress`); ensure
references to symboToNameMap remain intact and that tvlUsd calculation and the
URL property use the chain-specific price/address data.
|
The yo-protocol adapter exports pools: Test Suites: 1 passed, 1 total |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/adaptors/yo-protocol/index.js`:
- Around line 72-75: The code is hardcoding rewardTokens to
'0x1925450f5e5fb974b0aae1f3408cf5286fbd1a72' when building the object (see
vaultReward, apyReward, rewardTokens), which mislabels rewards for other
chains/opportunities; change the logic to first read reward token(s) from the
opportunity/vault data (check fields like opportunity.rewardTokens,
opportunity.rewardToken, vaultReward.*) and use those if present, otherwise fall
back to a documented chain-specific constant or null; update the construction
that spreads ...(vaultReward && { apyReward: Number(vaultReward.apr),
rewardTokens: [...] }) to derive rewardTokens from the opportunity/vaultReward
data or from a clearly named fallback constant so it’s not silently hardcoded.
| ...(vaultReward && { | ||
| apyReward: Number(vaultReward.apr), | ||
| rewardTokens: [vault.asset.address], | ||
| rewardTokens: ['0x1925450f5e5fb974b0aae1f3408cf5286fbd1a72'], | ||
| }), |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Inspect reward token fields in Merkl payload (if present)
curl -s 'https://api.merkl.xyz/v4/opportunities/?creatorAddress=0x8C9200d94Cf7A1B201068c4deDa6239F15FED480&status=LIVE' \
| jq '.[0] | {identifier, rewardTokens, rewardToken, chainId}'Repository: DefiLlama/yield-server
Length of output: 196
🏁 Script executed:
# Examine the code context around lines 72-75
head -85 src/adaptors/yo-protocol/index.js | tail -25Repository: DefiLlama/yield-server
Length of output: 690
🏁 Script executed:
# Check if there are multiple chains referenced in this adaptor
grep -n "chainId\|chain\|Chain" src/adaptors/yo-protocol/index.js | head -20Repository: DefiLlama/yield-server
Length of output: 283
🏁 Script executed:
# Look for other hardcoded token references in the file
grep -n "0x" src/adaptors/yo-protocol/index.jsRepository: DefiLlama/yield-server
Length of output: 255
🏁 Script executed:
# Look for vaultReward assignment and how it's obtained
grep -B 10 -A 5 "vaultReward" src/adaptors/yo-protocol/index.js | head -40Repository: DefiLlama/yield-server
Length of output: 1223
🏁 Script executed:
# Get full details of multiple opportunities from Merkl API
curl -s 'https://api.merkl.xyz/v4/opportunities/?creatorAddress=0x8C9200d94Cf7A1B201068c4deDa6239F15FED480&status=LIVE' \
| jq '.[] | {identifier, chainId, rewardTokens, rewardToken}' | head -60Repository: DefiLlama/yield-server
Length of output: 1360
🏁 Script executed:
# Check if there are any environment or config files that might map tokens
find src/adaptors/yo-protocol -type f -name "*.js" -o -name "*.json" | xargs catRepository: DefiLlama/yield-server
Length of output: 3258
The hardcoded reward token should be obtained from the opportunity data or clearly documented as a fallback.
The token '0x1925450f5e5fb974b0aae1f3408cf5286fbd1a72' is hardcoded at line 74 for all opportunities and chains, despite processing multiple vaults dynamically. The Merkl API response contains no reward token information (all rewardTokens and rewardToken fields are null), so this token is applied uniformly regardless of chain or opportunity configuration. If reward tokens differ by chain or opportunity, this will incorrectly label rewards across the board.
🤖 Prompt for AI Agents
In `@src/adaptors/yo-protocol/index.js` around lines 72 - 75, The code is
hardcoding rewardTokens to '0x1925450f5e5fb974b0aae1f3408cf5286fbd1a72' when
building the object (see vaultReward, apyReward, rewardTokens), which mislabels
rewards for other chains/opportunities; change the logic to first read reward
token(s) from the opportunity/vault data (check fields like
opportunity.rewardTokens, opportunity.rewardToken, vaultReward.*) and use those
if present, otherwise fall back to a documented chain-specific constant or null;
update the construction that spreads ...(vaultReward && { apyReward:
Number(vaultReward.apr), rewardTokens: [...] }) to derive rewardTokens from the
opportunity/vaultReward data or from a clearly named fallback constant so it’s
not silently hardcoded.
There was a problem hiding this comment.
we use only 1 token for reward distribution - 0x1925450f5e5fb974b0aae1f3408cf5286fbd1a72 thats why it's hardcoded
There was a problem hiding this comment.
@AndonMitev, thank you for the clarification! That makes sense – if yo-protocol uses a single reward token (0x1925450f5e5fb974b0aae1f3408cf5286fbd1a72) for all reward distributions across all vaults, then hardcoding it is the correct approach. I've noted this for future reviews.
✏️ Learnings added
Learnt from: AndonMitev
Repo: DefiLlama/yield-server PR: 2316
File: src/adaptors/yo-protocol/index.js:72-75
Timestamp: 2026-01-29T16:48:52.786Z
Learning: In src/adaptors/yo-protocol/index.js, the reward token address 0x1925450f5e5fb974b0aae1f3408cf5286fbd1a72 is intentionally hardcoded because yo-protocol uses only one token for reward distribution across all vaults and chains.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
Update pools to include reward APY from Merkl
Summary by CodeRabbit
New Features
Bug Fixes
Chores
✏️ Tip: You can customize this high-level summary in your review settings.