Skip to content

feat(metrom-adapter): add support for megaeth and pool meta information#2512

Open
luzzif wants to merge 3 commits intoDefiLlama:masterfrom
metrom-xyz:master
Open

feat(metrom-adapter): add support for megaeth and pool meta information#2512
luzzif wants to merge 3 commits intoDefiLlama:masterfrom
metrom-xyz:master

Conversation

@luzzif
Copy link
Copy Markdown
Contributor

@luzzif luzzif commented Mar 26, 2026

Summary by CodeRabbit

  • New Features
    • Added support for MegaETH blockchain.
    • Campaigns now include detailed pool and protocol metadata.
    • Improved protocol information display for Aave, Liquity v2, and decentralized exchange pools.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 26, 2026

📝 Walkthrough

Walkthrough

Added support for MegaETH chain, extended campaign target types with a new dex field, and implemented poolMeta field population across multiple campaign target types using a new humanizeTargetProtocol helper function for consistent protocol name formatting.

Changes

Cohort / File(s) Summary
Metrom Adaptor Enhancement
src/adaptors/metrom/index.ts
Added MegaETH chain mapping (4_326), extended AmmPoolLiquidityTarget with required dex field, added poolMeta: string to ProcessedCampaign, implemented poolMeta population across six target types (amm-pool-liquidity, liquity-v2-debt, liquity-v2-stability-pool, aave-v3-supply, aave-v3-borrow, aave-v3-net-supply), and added humanizeTargetProtocol helper function for consistent protocol slug formatting.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A new chain hops in (MegaETH so grand!),
Types get extended across the land,
poolMeta fields now sprouting with care,
Helper functions blooming everywhere,
Liquidity targets, nested and fair! 🌱

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the two main changes: adding MegaETH chain support and introducing pool meta information to campaigns.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ 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 and usage tips.

@llamatester
Copy link
Copy Markdown

The metrom adapter exports pools:

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

Nb of pools: 3
 

Sample pools:
┌─────────┬─────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────────────────────────────────────────────────────────┬─────────┬──────────┬────────────────────┬────────────────────┬──────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ (index) │ symbol      │ underlyingTokens                                                                                                                               │ poolMeta           │ pool                                                                 │ chain   │ project  │ apyReward          │ tvlUsd             │ rewardTokens                                                             │ url                                                                                                              │
├─────────┼─────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────────────────────────────────────────────────────────┼─────────┼──────────┼────────────────────┼────────────────────┼──────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 0       │ 'USDT'      │ [ '0x357b0b74bc833e95a115ad22604854d6b0fca151cecd94111770e5d6ffc9dc2b' ]                                                                       │ 'Net lend on Aave' │ '0x26714342f1b136b1e8833536b0203771a10349d2a66dc46b44524cb00ccde265' │ 'Aptos' │ 'metrom' │ 3.664910597408424  │ 12980603.45169996  │ [ '0x000000000000000000000000000000000000000000000000000000000000000a' ] │ 'https://app.metrom.xyz/en/campaigns/aptos/1/0x26714342f1b136b1e8833536b0203771a10349d2a66dc46b44524cb00ccde265' │
│ 1       │ 'USDC'      │ [ '0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b' ]                                                                       │ 'Net lend on Aave' │ '0x6de6c4253a42a445c3fe0bda8547c24778fb18b0cae769edcb8540ed09bde4f0' │ 'Aptos' │ 'metrom' │ 3.4006315451570868 │ 10662358.740264803 │ [ '0x000000000000000000000000000000000000000000000000000000000000000a' ] │ 'https://app.metrom.xyz/en/campaigns/aptos/1/0x6de6c4253a42a445c3fe0bda8547c24778fb18b0cae769edcb8540ed09bde4f0' │
│ 2       │ 'USD1-USDC' │ [ '0x05fabd1b12e39967a3c24e91b7b8f67719a6dacee74f3c8b9fb7d93e855437d2', '0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b' ] │ 'Pool on Hyperion' │ '0xf6118d185719a8bb3510e55c048536b06f932056de6e447405a6971774c2f4fd' │ 'Aptos' │ 'metrom' │ 0.9890930117188692 │ 603275.4423738134  │ [ '0x000000000000000000000000000000000000000000000000000000000000000a' ] │ 'https://app.metrom.xyz/en/campaigns/aptos/1/0xf6118d185719a8bb3510e55c048536b06f932056de6e447405a6971774c2f4fd' │
└─────────┴─────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────────────────────────────────────────────────────────┴─────────┴──────────┴────────────────────┴────────────────────┴──────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

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: 1

🧹 Nitpick comments (1)
src/adaptors/metrom/index.ts (1)

218-237: Consider extracting duplicated single-collateral branch mapping.

aave-v3-supply, aave-v3-borrow, and aave-v3-net-supply differ only by action string. A shared helper would reduce drift risk.

Refactor sketch
+function fromSingleCollateralTarget(
+  collateral: Token,
+  action: string,
+  protocol: string
+): ProcessedCampaign {
+  return {
+    symbol: formatSymbol(collateral.symbol),
+    underlyingTokens: [collateral.address],
+    poolMeta: humanizeTargetProtocol(action, protocol),
+  };
+}
...
-    case 'aave-v3-supply': {
-      return {
-        symbol: formatSymbol(campaign.target.collateral.symbol),
-        underlyingTokens: [campaign.target.collateral.address],
-        poolMeta: humanizeTargetProtocol('Lend on', campaign.target.brand),
-      };
-    }
+    case 'aave-v3-supply':
+      return fromSingleCollateralTarget(
+        campaign.target.collateral,
+        'Lend on',
+        campaign.target.brand
+      );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/adaptors/metrom/index.ts` around lines 218 - 237, The three case branches
('aave-v3-supply', 'aave-v3-borrow', 'aave-v3-net-supply') duplicate the same
mapping except for the action string; extract a helper (e.g.,
buildSingleCollateralMapping or mapAaveV3SingleCollateral) that accepts the
action label ("Lend on"/"Borrow on"/"Net lend on") and returns { symbol:
formatSymbol(campaign.target.collateral.symbol), underlyingTokens:
[campaign.target.collateral.address], poolMeta:
humanizeTargetProtocol(actionLabel, campaign.target.brand) }, then replace each
case to call that helper with the appropriate label to eliminate duplication
while keeping formatSymbol and humanizeTargetProtocol usage intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/adaptors/metrom/index.ts`:
- Around line 245-249: humanizeTargetProtocol can throw when protocolSlug is
undefined; update it to safely handle missing/empty values by defaulting
protocolSlug to an empty string (or a sentinel like "Unknown") before splitting
and by guarding word access in the mapper. Concretely, change
humanizeTargetProtocol to use (protocolSlug ?? '') or String(protocolSlug) and
.split('-').filter(Boolean) and map each word with safe access (e.g.,
word.charAt(0)?.toUpperCase() + word.slice(1)) so the function returns a
sensible string (like just the action or "action Unknown") instead of throwing.

---

Nitpick comments:
In `@src/adaptors/metrom/index.ts`:
- Around line 218-237: The three case branches ('aave-v3-supply',
'aave-v3-borrow', 'aave-v3-net-supply') duplicate the same mapping except for
the action string; extract a helper (e.g., buildSingleCollateralMapping or
mapAaveV3SingleCollateral) that accepts the action label ("Lend on"/"Borrow
on"/"Net lend on") and returns { symbol:
formatSymbol(campaign.target.collateral.symbol), underlyingTokens:
[campaign.target.collateral.address], poolMeta:
humanizeTargetProtocol(actionLabel, campaign.target.brand) }, then replace each
case to call that helper with the appropriate label to eliminate duplication
while keeping formatSymbol and humanizeTargetProtocol usage intact.
🪄 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: b6ef77a3-503e-4265-9b39-586f932404fa

📥 Commits

Reviewing files that changed from the base of the PR and between 00a0607 and 6ce5a51.

📒 Files selected for processing (1)
  • src/adaptors/metrom/index.ts

Comment on lines +245 to +249
function humanizeTargetProtocol(action: string, protocolSlug: string): string {
return `${action} ${protocolSlug
.split('-')
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ')}`;
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Make humanizeTargetProtocol resilient to missing protocol values.

At Line 246, .split('-') will throw if upstream payloads omit dex/brand, and the caller then drops the entire campaign in the catch block.

Proposed fix
-function humanizeTargetProtocol(action: string, protocolSlug: string): string {
-  return `${action} ${protocolSlug
-    .split('-')
+function humanizeTargetProtocol(
+  action: string,
+  protocolSlug?: string
+): string {
+  const normalizedSlug = protocolSlug?.trim();
+  if (!normalizedSlug) return action;
+
+  return `${action} ${normalizedSlug
+    .split(/[-_]/)
     .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
     .join(' ')}`;
 }
📝 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
function humanizeTargetProtocol(action: string, protocolSlug: string): string {
return `${action} ${protocolSlug
.split('-')
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ')}`;
function humanizeTargetProtocol(
action: string,
protocolSlug?: string
): string {
const normalizedSlug = protocolSlug?.trim();
if (!normalizedSlug) return action;
return `${action} ${normalizedSlug
.split(/[-_]/)
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ')}`;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/adaptors/metrom/index.ts` around lines 245 - 249, humanizeTargetProtocol
can throw when protocolSlug is undefined; update it to safely handle
missing/empty values by defaulting protocolSlug to an empty string (or a
sentinel like "Unknown") before splitting and by guarding word access in the
mapper. Concretely, change humanizeTargetProtocol to use (protocolSlug ?? '') or
String(protocolSlug) and .split('-').filter(Boolean) and map each word with safe
access (e.g., word.charAt(0)?.toUpperCase() + word.slice(1)) so the function
returns a sensible string (like just the action or "action Unknown") instead of
throwing.

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.

@luzzif pls implement this fix to future proof

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.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

symbol: formatSymbol(campaign.target.collateral.symbol),
underlyingTokens: [campaign.target.collateral.address],
poolMeta: humanizeTargetProtocol(
'Deposit to stability pool on',
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.

please reduce the text too long and wont easily be seen

Copy link
Copy Markdown
Contributor

@0xkr3p 0xkr3p Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stability pool - brand

Copy link
Copy Markdown
Contributor

@0xkr3p 0xkr3p left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey @luzzif, thanks for the PR just a couple of really minor comments!

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.

3 participants