Skip to content

Split Native monad credit pool into native-lend-monad#20002

Open
June-native wants to merge 2 commits into
DefiLlama:mainfrom
June-native:feat/native-monad-ts
Open

Split Native monad credit pool into native-lend-monad#20002
June-native wants to merge 2 commits into
DefiLlama:mainfrom
June-native:feat/native-monad-ts

Conversation

@June-native

@June-native June-native commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Native Credit Pool: split monad into doublecounted adapter + add xlayer, morph, robinhood

1. New native-lend-monad adapter (doublecounted)

Moves the monad Credit Vault (0xcD1D2D602C3e7394515DaAe96e4FFe16DE71e5B4) out of native-lend into a new native-lend-monad adapter flagged doublecounted: true.

This vault is curated by Native but whitelabeled/owned by TownSquare, who track the same vault in a separate townsquare-vaults adapter. Splitting it out as doublecounted lets both Native (curator) and TownSquare (protocol owner) attribute the TVL without inflating aggregate DeFi TVL.

2. Added remaining Credit Vault chains to native-lend

Added the remaining Credit Vaults per the Native docs:

Chain Credit Vault vaultFromBlock
xlayer 0x4Df7557734B382EB542BEa6c74786D398DF4CC19 59885325
morph 0x4Df7557734B382EB542BEa6c74786D398DF4CC19 23245775
robinhood 0x57B8f68ef57Af2dB70BC9aAc891836661CA4cB51 60423

Changes

  • projects/native-lend/index.js: removed monad; added xlayer, morph, robinhood (existing eth/bsc/base/arbitrum unchanged).
  • projects/native-lend-monad/index.js: new monad-only adapter reusing the existing MarketListed / underlying / totalUnderlying tvl + borrowed logic, with doublecounted: true and updated methodology.

Summary by CodeRabbit

  • New Features

    • Added Native Lend coverage for Monad, including vault TVL and borrowed balance tracking.
    • Included vault methodology details and protection against aggregated TVL inflation.
  • Updates

    • Updated the main Native Lend adapter set by removing Monad and adding support for XLayer, Morph, and Robinhood (Arbitrum remains).

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a Native Lend adapter for a Native-curated Monad vault, including TVL and borrowed calculations, and updates the existing Native Lend configuration to support X Layer, Morph, and Robinhood instead of Monad.

Changes

Native Lend adapters

Layer / File(s) Summary
Monad adapter discovery and balance calculations
projects/native-lend-monad/index.js
Adds Monad vault metadata and configuration, discovers LP markets, resolves underlying tokens, calculates TVL, and derives borrowed balances from locked and cash amounts.
Existing adapter chain configuration
projects/native-lend/index.js
Removes the Monad configuration and adds X Layer, Morph, and Robinhood vaults with their starting blocks.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant NativeLendMonadAdapter
  participant MonadRPC
  participant LPMarkets
  participant UnderlyingTokens
  participant Vault
  NativeLendMonadAdapter->>MonadRPC: getLogs MarketListed(address)
  MonadRPC-->>NativeLendMonadAdapter: listed LP tokens
  NativeLendMonadAdapter->>LPMarkets: multicall underlying()
  LPMarkets-->>NativeLendMonadAdapter: underlying token addresses
  NativeLendMonadAdapter->>Vault: sumTokens2 cash balances
  Vault-->>NativeLendMonadAdapter: TVL balances
  NativeLendMonadAdapter->>LPMarkets: multicall totalUnderlying()
  LPMarkets-->>NativeLendMonadAdapter: locked amounts
  NativeLendMonadAdapter->>UnderlyingTokens: balanceOf(vault)
  UnderlyingTokens-->>NativeLendMonadAdapter: cash balances
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title is concise and accurately summarizes the main change: splitting the Monad credit pool into a new adapter.
Description check ✅ Passed The description clearly explains the split, the new chain additions, and the methodology; the template’s new-listing fields are not applicable here.
✨ 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 adapter at projects/native-lend exports TVL:

ethereum                  23.74 M
borrowed                  19.06 M
ethereum-borrowed         19.02 M
bsc                       6.23 M
arbitrum                  1.33 M
base                      762.34 k
bsc-borrowed              40.99 k
base-borrowed             0.00
arbitrum-borrowed         0.00

total                    32.06 M 

@github-actions

Copy link
Copy Markdown

The adapter at projects/native-lend-monad exports TVL:

monad                     465.00
monad-borrowed            0.00
borrowed                  0.00

total                    465.44 

@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)
projects/native-lend-monad/index.js (1)

24-37: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract shared LP discovery logic to avoid duplication.

The LP token discovery (getLogs for MarketListed + multiCall for underlying) is identical in both tvl and borrowed. Any future change to event ABI, log fetching, or token resolution must be applied in two places, risking divergence.

♻️ Proposed refactor
+async function getLpUnderlyingTokens(api, vault, vaultFromBlock) {
+  const lpListedLogs = await getLogs({
+    api,
+    target: vault,
+    topic: "MarketListed(address)",
+    eventAbi: "event MarketListed(address lpToken)",
+    onlyArgs: true,
+    fromBlock: vaultFromBlock,
+  });
+  const lps = lpListedLogs.map((i) => i.lpToken);
+  const tokens = await api.multiCall({ abi: 'address:underlying', calls: lps });
+  return { lps, tokens };
+}
+
 Object.keys(config).forEach((chain) => {
   // get vault and start block
   const { vault, vaultFromBlock } = config[chain];
   module.exports[chain] = {
     tvl: async (api) => {
-      // get all lps
-      const lpListedLogs = await getLogs({
-        api,
-        target: vault,
-        topic: "MarketListed(address)",
-        eventAbi:
-          "event MarketListed(address lpToken)",
-        onlyArgs: true,
-        fromBlock: vaultFromBlock,
-      });
-      const lps = lpListedLogs.map((i) => i.lpToken);
-
-      // get all underlying tokens
-      const tokens = await api.multiCall({ abi: 'address:underlying', calls: lps });
+      const { tokens } = await getLpUnderlyingTokens(api, vault, vaultFromBlock);

       // use sumTokens2 to for cash balances in vault
       return sumTokens2({
         api,
         owner: vault,
         tokens
       });
     },
     borrowed: async (api) => {
-      // get all lps
-      const lpListedLogs = await getLogs({
-        api,
-        target: vault,
-        topic: "MarketListed(address)",
-        eventAbi:
-          "event MarketListed(address lpToken)",
-        onlyArgs: true,
-        fromBlock: vaultFromBlock,
-      });
-      const lps = lpListedLogs.map((i) => i.lpToken);
-
-      // get all underlying tokens
-      const tokens = await api.multiCall({ abi: 'address:underlying', calls: lps });
+      const { lps, tokens } = await getLpUnderlyingTokens(api, vault, vaultFromBlock);

       // get total supplied
       let v2Locked = await api.multiCall({ abi: 'address:totalUnderlying', calls: lps });

Also applies to: 47-60

🤖 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 `@projects/native-lend-monad/index.js` around lines 24 - 37, Extract the
duplicated LP discovery sequence from both tvl and borrowed into a shared helper
that fetches MarketListed logs via getLogs and resolves underlying tokens via
api.multiCall. Replace both inline implementations with calls to this helper,
preserving the existing vault, vaultFromBlock, and API inputs and returned
LP/token data.
🤖 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 `@projects/native-lend-monad/index.js`:
- Line 63: Update the borrowed-balance calculations around v2Locked in both
native-lend-monad/index.js and native-lend/index.js to call totalUnderlying with
the uint256 ABI and perform subtraction using BigInt values instead of parseInt
or Number arithmetic. Preserve the existing locked-minus-cash behavior while
avoiding precision loss for large balances.

---

Nitpick comments:
In `@projects/native-lend-monad/index.js`:
- Around line 24-37: Extract the duplicated LP discovery sequence from both tvl
and borrowed into a shared helper that fetches MarketListed logs via getLogs and
resolves underlying tokens via api.multiCall. Replace both inline
implementations with calls to this helper, preserving the existing vault,
vaultFromBlock, and API inputs and returned LP/token data.
🪄 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: 2971f5e3-140a-4bfa-867b-ea2ab2a558a8

📥 Commits

Reviewing files that changed from the base of the PR and between ecc5f22 and 4d89711.

📒 Files selected for processing (2)
  • projects/native-lend-monad/index.js
  • projects/native-lend/index.js
💤 Files with no reviewable changes (1)
  • projects/native-lend/index.js

const tokens = await api.multiCall({ abi: 'address:underlying', calls: lps });

// get total supplied
let v2Locked = await api.multiCall({ abi: 'address:totalUnderlying', calls: lps });

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify the totalUnderlying function return type on the vault's LP contracts.
# Check if the existing native-lend adapter uses the same ABI pattern.
rg -n "totalUnderlying" projects/native-lend/ --type=js

# Also search for other adapters using address:totalUnderlying to see if this is a common pattern.
rg -n "address:totalUnderlying" projects/ --type=js | head -20

Repository: DefiLlama/DefiLlama-Adapters

Length of output: 541


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== native-lend-monad/index.js around the reported lines =="
sed -n '1,140p' projects/native-lend-monad/index.js | cat -n

echo
echo "== native-lend/index.js around the matching logic =="
sed -n '1,140p' projects/native-lend/index.js | cat -n

echo
echo "== search for parseInt usage in these adapters =="
rg -n "parseInt|BigInt|totalUnderlying|balanceOf" projects/native-lend-monad/index.js projects/native-lend/index.js

Repository: DefiLlama/DefiLlama-Adapters

Length of output: 8395


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== typed ABI examples in the repo =="
rg -n "abi: 'address:[^']+'|abi: \"address:[^\"]+\"|abi: 'uint256:[^']+'|abi: \"uint256:[^\"]+\"" projects helper | head -100

echo
echo "== any explicit totalUnderlying ABI definitions or contract source references =="
rg -n "totalUnderlying|MarketListed|underlying" . --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' | head -200

Repository: DefiLlama/DefiLlama-Adapters

Length of output: 11944


🌐 Web query:

Native Lend Monad totalUnderlying return type lp contract verified source

💡 Result:

The term Native Lend typically refers to a decentralized finance protocol or infrastructure layer, rather than a single specific standard contract that shares a uniform return type for a totalUnderlying function across all implementations. In various lending and liquidity pool protocols, the totalUnderlying function is commonly implemented to return a single uint256 value representing the total quantity of the underlying asset held by the contract or pool [1][2]. However, its exact signature and return type depend on the specific protocol's architecture: 1. Standard Lending/Pool Protocols: In many liquidity pool and lending contracts (such as various implementations found in DeFi protocol audits), totalUnderlying is defined to return a single uint256 [1][2]. This value aggregates the balance of the underlying asset held within the pool or vault [1][2]. 2. LP/Position Modules: In other specialized protocols like Arrakis Finance, which manage liquidity positions involving multiple assets (e.g., Uniswap V3 positions), the totalUnderlying function is designed to return a tuple of multiple values, specifically (uint256 amount0, uint256 amount1), representing the quantities of each underlying token in the position [3][4][5]. There is no singular verified source or universal standard for a Native Lend protocol's totalUnderlying return type on Monad. Because Monad is an EVM-compatible blockchain, developers often use varying architectural patterns (such as those from Fluid, Arrakis, or other lending frameworks) [6][7][3]. To verify the specific return type for a contract on Monad, you must examine the specific source code or the ABI for that particular deployment [8]. If the contract is verified on a blockchain explorer (like Etherscan-based explorers commonly used for Monad), you can inspect the Read Contract tab or the source code tab to confirm the specific function signature and return type.

Citations:


Use uint256:totalUnderlying and BigInt for the borrowed-balance math. parseInt(...) can lose precision once balances exceed Number.MAX_SAFE_INTEGER, so locked - cash can be wrong for large pools. The same change applies to the mirrored logic in projects/native-lend/index.js.

🤖 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 `@projects/native-lend-monad/index.js` at line 63, Update the borrowed-balance
calculations around v2Locked in both native-lend-monad/index.js and
native-lend/index.js to call totalUnderlying with the uint256 ABI and perform
subtraction using BigInt values instead of parseInt or Number arithmetic.
Preserve the existing locked-minus-cash behavior while avoiding precision loss
for large balances.

Source: Learnings

@github-actions

Copy link
Copy Markdown

The adapter at projects/native-lend exports TVL:

ethereum                  23.74 M
borrowed                  18.95 M
ethereum-borrowed         18.91 M
bsc                       6.23 M
arbitrum                  1.33 M
base                      759.91 k
xlayer                    99.25 k
robinhood                 50.27 k
bsc-borrowed              40.99 k
morph                     118.00
base-borrowed             0.00
arbitrum-borrowed         0.00
robinhood-borrowed        0.00
xlayer-borrowed           0.00
morph-borrowed            0.00

total                    32.20 M 

@github-actions

Copy link
Copy Markdown

The adapter at projects/native-lend-monad exports TVL:

monad                     465.00
monad-borrowed            0.00
borrowed                  0.00

total                    465.50 

@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

🤖 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 `@projects/native-lend/index.js`:
- Around line 25-35: Update the shared borrowed-balance calculation in the
native-lend configuration flow to avoid parseInt and preserve full uint256
precision using bigint or string arithmetic. Keep values precise through
intermediate calculations, converting only at the SDK boundary, including for
xlayer, morph, robinhood, and other chains using this path.
🪄 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: 30cfaaae-db54-4b68-abbb-c62e82f92937

📥 Commits

Reviewing files that changed from the base of the PR and between 4d89711 and d70d066.

📒 Files selected for processing (1)
  • projects/native-lend/index.js

Comment on lines +25 to +35
xlayer: {
vault: "0x4Df7557734B382EB542BEa6c74786D398DF4CC19",
vaultFromBlock: 59885325,
},
morph: {
vault: "0x4Df7557734B382EB542BEa6c74786D398DF4CC19",
vaultFromBlock: 23245775,
},
robinhood: {
vault: "0x57B8f68ef57Af2dB70BC9aAc891836661CA4cB51",
vaultFromBlock: 60423,

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the relevant file and locate the borrowed implementation.
git ls-files projects/native-lend/index.js
ast-grep outline projects/native-lend/index.js --view expanded || true

# Show the surrounding lines around the reported region and borrowed implementation.
nl -ba projects/native-lend/index.js | sed -n '1,220p'

Repository: DefiLlama/DefiLlama-Adapters

Length of output: 280


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the file with line numbers, then jump to the borrowed implementation.
cat -n projects/native-lend/index.js | sed -n '1,220p'

printf '\n--- parseInt search ---\n'
rg -n "parseInt|borrowed|totalUnderlying|balanceOf" projects/native-lend/index.js

Repository: DefiLlama/DefiLlama-Adapters

Length of output: 4738


Preserve precision in the borrowed path. parseInt will lose precision for 18-decimal uint256 values above 2^53 - 1, so this shared calculation can underreport borrowed balances on any chain using it, including the newly added ones. Use bigint/string arithmetic here and convert only at the SDK boundary.

🤖 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 `@projects/native-lend/index.js` around lines 25 - 35, Update the shared
borrowed-balance calculation in the native-lend configuration flow to avoid
parseInt and preserve full uint256 precision using bigint or string arithmetic.
Keep values precise through intermediate calculations, converting only at the
SDK boundary, including for xlayer, morph, robinhood, and other chains using
this path.

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.

1 participant