Updating Verified Network TVL with custodial wallets#17954
Updating Verified Network TVL with custodial wallets#17954kallolborah wants to merge 37 commits intoDefiLlama:mainfrom
Conversation
feat: ethereum update
My branch behind updates
Submission for Verified Network
My branch update
My branch Update with Defillama main
My branch Update
Changed api to Defillama sdk
Merge pull request #8 from verified-network/new-update
|
Error while running adapter at projects/verified: |
📝 WalkthroughWalkthroughReplaced subgraph pool-fetching with a paginated GraphQL helper and added per-chain address-based TVL computation for Ethereum, NEAR, and Solana. Introduced chain-specific balance fetchers, unit-conversion helpers, a dispatcher for address TVL, and conditional export wiring to prefer subgraphUrl or fallback to address-based TVL. Changes
Sequence DiagramsequenceDiagram
participant Module as TVL Module
participant Dispatcher as getAddressTvl
participant EthRPC as Ethereum RPC / API
participant NearRPC as NEAR RPC / API
participant SolRPC as Solana RPC / API
participant Subgraph as Subgraph (GraphQL)
Module->>Subgraph: fetchAllPools(subgraphUrl) [if subgraphUrl]
Subgraph-->>Module: paginated pools list
Module->>Dispatcher: getAddressTvl(chain, address) [if no subgraphUrl]
Dispatcher->>Dispatcher: determine chain
alt Ethereum
Dispatcher->>EthRPC: getEthBalance(address)
EthRPC-->>Dispatcher: ETH balances
Dispatcher-->>Module: formatted balances (ethers.parseUnits)
else NEAR
Dispatcher->>NearRPC: getNearBalance(address)
NearRPC-->>Dispatcher: raw NEAR (yocto)
Dispatcher->>Dispatcher: yoctoToNear()
Dispatcher-->>Module: formatted NEAR balance
else Solana
Dispatcher->>SolRPC: getSolBalance(address)
SolRPC-->>Dispatcher: SOL balance
Dispatcher-->>Module: formatted SOL balance
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 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: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
projects/verified/index.js (1)
287-288:⚠️ Potential issue | 🟠 Major
timetravel: trueis incompatible with address-based balance fetching.The new
getEthBalance,getNearBalance, andgetSolBalancefunctions always query the latest on-chain state (e.g.,"latest"block for ETH,"final"finality for NEAR). They ignore the timestamp parameter passed by DefiLlama. Settingtimetravel: trueis misleading — historical TVL queries for NEAR and Solana chains will return current balances, not historical ones.Consider setting
timetravel: false, or implementing proper historical block lookups for the address-based chains.
🤖 Fix all issues with AI agents
In `@projects/verified/index.js`:
- Around line 162-168: The merging loop over chainBalance incorrectly uses
.map() for side effects and uses + which can concatenate strings; replace
Object.keys(chainBalance).map(...) with Object.keys(chainBalance).forEach(...)
and call sdk.util.sumSingleBalance(balances, tk, chainBalance[tk]) (or
equivalent sdk util merge function) to safely sum values; update the block
around getAddressTvl, chainsConfig, chainBalance and balances to use forEach and
sdk.util.sumSingleBalance so numeric/string balances are merged correctly.
- Around line 293-303: chainsConfig entries with both subgraphUrl and address
are causing double-counting because the module.exports loop uses
getChainTvls(chain) for subgraph-enabled chains while getChainTvls itself also
merges chainsConfig[chain].address balances; update the logic so only one source
is applied: either remove/disable the address-merge inside getChainTvls(chain)
when chainsConfig[chain].subgraphUrl exists, or change the module.exports loop
to prefer address-only (call getAddressTvl) when both are present; modify the
code paths around chainsConfig, getChainTvls, and getAddressTvl to make the
behavior explicit (or add a config flag like includeAddressWithSubgraph) and
document the chosen behavior.
- Line 191: Replace unsafe Number(...) conversions and floating-point
reconstruction with integer-safe handling: stop passing Number(data.result) to
sdk.util.sumSingleBalance and instead parse hex/decimal balances into BigInt (or
use the SDK's integer/string balance helpers) and supply the correctly scaled
string/BigInt; for NEAR, avoid parsing yoctoToNear to a float then multiplying
by 10**18—work directly with yocto (24-decimal) amounts or use a string-based
big-number utility to convert to the target unit; similarly replace
Number(data.result.value) for Solana lamports with BigInt/string arithmetic
before calling sdk.util.sumSingleBalance so no precision is lost.
- Around line 3-7: The file contains unresolved git conflict markers (<<<<<<<,
=======, >>>>>>>) which break parsing; open the affected file, remove all
conflict markers and merge the intended changes by rebasing or merging the
target branch, keeping the correct definitions (e.g., the intended const {
ZeroAddress } require("ethers") line and any other current declarations or
exports) and discarding the alternate/conflict sections; verify you preserved
the correct exports/functions and then run the linter/tests to confirm no parse
errors remain.
- Around line 190-191: Resolve the leftover merge conflict and fix native token
handling: remove the manual `ethereum:${ZeroAddress?.toLowerCase()}` style key
and instead use the SDK/native helpers when summing balances in the Ethereum,
NEAR, and Solana balance-fetching functions; for Ethereum prefer using
api.sumTokens with ADDRESSES.null or use sdk.util.sumSingleBalance(balances,
ADDRESSES.null, Number(data.result)) referencing ZeroAddress only in Ethereum
adapters where ADDRESSES.null is defined, and for NEAR/Solana replace
`near:${ZeroAddress?.toLowerCase()}` and `solana:${ZeroAddress?.toLowerCase()}`
with sdk.util.sumSingleBalance(balances, nullAddress, amount, 'near') and
sdk.util.sumSingleBalance(balances, nullAddress, amount, 'solana') respectively
(see functions that call sdk.util.sumSingleBalance and api.sumTokens for exact
placement).
- Around line 173-195: getEthBalance, getNearBalance, and getSolBalance are
making raw fetch JSON-RPC calls without error handling or using the project's
SDK/helpers; replace those raw fetches with the proper SDK/helper calls (use
sdk.api.eth.getBalance for Ethereum, the RPC helper pattern from
projects/helper/chain/near.js for NEAR, and `@solana/web3.js` connection helpers
like getSolBalanceFromStakePool for Solana), add null-checks/validation around
RPC responses before accessing properties (e.g., guard data.result /
data.result.amount / data.result.value), and implement retry/timeout/fallback
logic consistent with the NEAR helper; ensure the final balances are summed via
sdk.util.sumSingleBalance (retain token format like
`ethereum:${ZeroAddress?.toLowerCase()}`) and surface/log RPC errors instead of
throwing unhandled exceptions.
🧹 Nitpick comments (1)
projects/verified/index.js (1)
10-10: Stale TODO comment.Line 10 still has
//TODO: add more chains— this is now addressed by the addition of NEAR and Solana. Consider removing or updating the comment.
projects/verified/index.js
Outdated
| <<<<<<< HEAD | ||
| const { ZeroAddress } = require("ethers"); | ||
| ======= | ||
|
|
||
| >>>>>>> 2a4f43188a6cf52d2ab336d5ef4b3928382da581 |
There was a problem hiding this comment.
Critical: Unresolved git merge conflict markers throughout the file.
The file contains at least six sets of <<<<<<< HEAD / ======= / >>>>>>> conflict markers (lines 3–7, 17–41, 89–92, 116–120, 160–282, 291–309). This is not valid JavaScript and will fail to parse at runtime. The static analysis tool confirms dozens of resulting parse errors.
You must resolve all merge conflicts before this PR can be reviewed or merged. Please rebase or merge the target branch and resolve conflicts, keeping only the intended code.
Also applies to: 17-41, 89-92, 116-120, 160-282, 291-309
🧰 Tools
🪛 Biome (2.3.13)
[error] 4-7: Expected a statement but instead found '=======
2a4f431'.
Expected a statement here.
(parse)
[error] 7-7: numbers cannot be followed by identifiers directly after
an identifier cannot appear here
(parse)
🤖 Prompt for AI Agents
In `@projects/verified/index.js` around lines 3 - 7, The file contains unresolved
git conflict markers (<<<<<<<, =======, >>>>>>>) which break parsing; open the
affected file, remove all conflict markers and merge the intended changes by
rebasing or merging the target branch, keeping the correct definitions (e.g.,
the intended const { ZeroAddress } require("ethers") line and any other current
declarations or exports) and discarding the alternate/conflict sections; verify
you preserved the correct exports/functions and then run the linter/tests to
confirm no parse errors remain.
| if(chainsConfig[chain].address) { | ||
| //if address exist on chain fetch it balance and compute new TVL | ||
| const chainBalance = await getAddressTvl(chain, chainsConfig[chain].address)(); | ||
| Object.keys(chainBalance).map((tk) => { | ||
| balances[tk] = balances[tk] ? balances[tk] + chainBalance[tk] : chainBalance[tk] | ||
| }) | ||
| } |
There was a problem hiding this comment.
Balance merging logic has potential string concatenation bug and misuses .map().
Object.keys(chainBalance).map((tk) => {
balances[tk] = balances[tk] ? balances[tk] + chainBalance[tk] : chainBalance[tk]
})- SDK balance values may be strings. The
+operator on two string values concatenates rather than adds (e.g.,"100" + "200"→"100200"). Usesdk.util.sumSingleBalanceto merge, which handles this correctly. .map()is used purely for side effects —.forEach()is the idiomatic choice.
Proposed fix
- Object.keys(chainBalance).map((tk) => {
- balances[tk] = balances[tk] ? balances[tk] + chainBalance[tk] : chainBalance[tk]
- })
+ Object.keys(chainBalance).forEach((tk) => {
+ sdk.util.sumSingleBalance(balances, tk, chainBalance[tk]);
+ });🧰 Tools
🪛 Biome (2.3.13)
[error] 162-162: Expected a JSX attribute but instead found '('.
Expected a JSX attribute here.
(parse)
[error] 162-162: Expected a JSX attribute but instead found '['.
Expected a JSX attribute here.
(parse)
[error] 162-162: Expected a JSX attribute but instead found '].'.
Expected a JSX attribute here.
(parse)
[error] 162-162: Expected a JSX attribute but instead found ')'.
Expected a JSX attribute here.
(parse)
[error] 164-164: expected ... but instead found const
Remove const
(parse)
[error] 164-164: Expected a JSX attribute value but instead found 'await'.
Expected a JSX attribute value here.
(parse)
[error] 164-164: Expected a JSX attribute but instead found '('.
Expected a JSX attribute here.
(parse)
[error] 164-164: Expected a JSX attribute but instead found ','.
Expected a JSX attribute here.
(parse)
[error] 164-164: Expected a JSX attribute but instead found '['.
Expected a JSX attribute here.
(parse)
[error] 164-164: Expected a JSX attribute but instead found '].'.
Expected a JSX attribute here.
(parse)
[error] 164-164: Expected a JSX attribute but instead found ')();'.
Expected a JSX attribute here.
(parse)
[error] 165-165: Expected a JSX attribute but instead found '.'.
Expected a JSX attribute here.
(parse)
[error] 165-165: Expected a JSX attribute but instead found '('.
Expected a JSX attribute here.
(parse)
[error] 165-165: Expected a JSX attribute but instead found ').'.
Expected a JSX attribute here.
(parse)
[error] 165-165: Expected a JSX attribute but instead found '(('.
Expected a JSX attribute here.
(parse)
[error] 165-165: Expected a JSX attribute but instead found ') =>'.
Expected a JSX attribute here.
(parse)
[error] 166-166: expected ... but instead found balances
Remove balances
(parse)
[error] 167-167: Expected a JSX attribute but instead found ')'.
Expected a JSX attribute here.
(parse)
[error] 168-168: Unexpected token. Did you mean {'}'} or }?
(parse)
🤖 Prompt for AI Agents
In `@projects/verified/index.js` around lines 162 - 168, The merging loop over
chainBalance incorrectly uses .map() for side effects and uses + which can
concatenate strings; replace Object.keys(chainBalance).map(...) with
Object.keys(chainBalance).forEach(...) and call
sdk.util.sumSingleBalance(balances, tk, chainBalance[tk]) (or equivalent sdk
util merge function) to safely sum values; update the block around
getAddressTvl, chainsConfig, chainBalance and balances to use forEach and
sdk.util.sumSingleBalance so numeric/string balances are merged correctly.
| const getEthBalance = (address) => { | ||
| return async (_, __, ___) => { | ||
| const res = await fetch("https://eth-mainnet.public.blastapi.io", { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/json" }, | ||
| body: JSON.stringify({ | ||
| jsonrpc: "2.0", | ||
| id: 1, | ||
| method: "eth_getBalance", | ||
| params: [address, "latest"], | ||
| }), | ||
| }); | ||
|
|
||
| const data = await res.json(); | ||
|
|
||
| let balances = {}; | ||
|
|
||
| const token = `ethereum:${ZeroAddress?.toLowerCase()}`; | ||
| sdk.util.sumSingleBalance(balances, token, Number(data.result)); | ||
|
|
||
| return balances; | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, get file size and read the relevant sections
wc -l projects/verified/index.jsRepository: DefiLlama/DefiLlama-Adapters
Length of output: 102
🏁 Script executed:
# Read the sections mentioned in the review
sed -n '173,195p' projects/verified/index.js
echo "---"
sed -n '212,239p' projects/verified/index.js
echo "---"
sed -n '241,263p' projects/verified/index.jsRepository: DefiLlama/DefiLlama-Adapters
Length of output: 1857
🏁 Script executed:
# Check for SDK api usage patterns in the codebase
rg -n 'sdk\.api\.' projects/verified/index.js | head -50Repository: DefiLlama/DefiLlama-Adapters
Length of output: 54
🏁 Script executed:
# Check if SDK has balance-related methods documented or used elsewhere
rg -n 'sdk\.api\.(eth|near|solana)' --type=js | head -30Repository: DefiLlama/DefiLlama-Adapters
Length of output: 2188
🏁 Script executed:
# Search for near/solana sdk.api usage
rg -n 'sdk\.api\.(near|solana)' --type=js | head -20Repository: DefiLlama/DefiLlama-Adapters
Length of output: 54
🏁 Script executed:
# Also search for alternative balance query patterns for near/sol
rg -n 'getNearBalance|getSolBalance' --type=jsRepository: DefiLlama/DefiLlama-Adapters
Length of output: 5263
🏁 Script executed:
# Check the beginning of the file to understand SDK context and imports
head -50 projects/verified/index.jsRepository: DefiLlama/DefiLlama-Adapters
Length of output: 1442
🏁 Script executed:
# Check if there's a NEAR helper similar to solana.js
find projects -name "*near*" -type f | grep -i helper | head -10Repository: DefiLlama/DefiLlama-Adapters
Length of output: 101
🏁 Script executed:
# Search for NEAR balance patterns in projects
rg -n 'near.*balance' -i --type=js | grep -v node_modules | head -20Repository: DefiLlama/DefiLlama-Adapters
Length of output: 2041
🏁 Script executed:
# Check package.json for `@defillama/sdk` to see if docs mention api availability
cat package.json | grep -A 5 defillama/sdkRepository: DefiLlama/DefiLlama-Adapters
Length of output: 267
🏁 Script executed:
# Check the NEAR helper for SDK usage patterns
cat -n projects/helper/chain/near.js | head -200Repository: DefiLlama/DefiLlama-Adapters
Length of output: 7667
🏁 Script executed:
# Check for sdk.api availability by searching SDK documentation patterns
rg -n 'sdk\.api\.' projects/helper/ --type=js | grep -E '(near|solana|sol)' | head -10Repository: DefiLlama/DefiLlama-Adapters
Length of output: 54
🏁 Script executed:
# Let me check if there's SDK documentation or README about chain APIs
find . -name "README*" -o -name "USAGE*" -type f | xargs grep -l "sdk.api" 2>/dev/null | head -5Repository: DefiLlama/DefiLlama-Adapters
Length of output: 54
🏁 Script executed:
# Check what SDK methods are available in `@defillama/sdk`
rg -n 'sdk\.api\.' projects/helper/chain/ --type=js | head -20Repository: DefiLlama/DefiLlama-Adapters
Length of output: 54
🏁 Script executed:
# Look at getSolBalanceFromStakePool to see the pattern
sed -n '400,450p' projects/helper/solana.jsRepository: DefiLlama/DefiLlama-Adapters
Length of output: 1599
Replace raw fetch calls with proper SDK or helper patterns; add error handling.
getEthBalance, getNearBalance, and getSolBalance make direct JSON-RPC calls to public endpoints without error handling. This is unsafe and inconsistent with established patterns in the codebase:
- Unsafe property access — Functions access nested properties (
data.result,data.result.amount,data.result.value) without null-checking or verifying the RPC response succeeded. Errors will be unhandled and crash the adapter. - Public endpoints lack resilience — No retry logic, fallback endpoints, or timeout handling. The NEAR helper (
projects/helper/chain/near.js) demonstrates the proper pattern: retry logic, error checking, and multiple endpoints. - Inconsistent with codebase standards — For Ethereum, use
sdk.api.eth.getBalance()(widely used throughout). For NEAR, use the patterns fromprojects/helper/chain/near.jswhich properly handles RPC calls with validation. For Solana, use@solana/web3.jsconnection patterns likegetSolBalanceFromStakePool().
Also applies to: 212-239, 241-263
🧰 Tools
🪛 Biome (2.3.13)
[error] 173-173: Unexpected token. Did you mean {'>'} or >?
(parse)
[error] 174-174: expected } but instead found return
Remove return
(parse)
[error] 174-174: Unexpected token. Did you mean {'>'} or >?
(parse)
[error] 175-175: expected } but instead found const
Remove const
(parse)
[error] 176-176: expected } but instead found :
Remove :
(parse)
[error] 177-177: expected } but instead found :
Remove :
(parse)
[error] 177-177: Unexpected token. Did you mean {'}'} or }?
(parse)
[error] 179-179: expected } but instead found :
Remove :
(parse)
[error] 183-183: Unexpected token. Did you mean {'}'} or }?
(parse)
[error] 184-184: Unexpected token. Did you mean {'}'} or }?
(parse)
[error] 193-194: Unexpected token. Did you mean {'}'} or }?
(parse)
[error] 194-195: Unexpected token. Did you mean {'}'} or }?
(parse)
🤖 Prompt for AI Agents
In `@projects/verified/index.js` around lines 173 - 195, getEthBalance,
getNearBalance, and getSolBalance are making raw fetch JSON-RPC calls without
error handling or using the project's SDK/helpers; replace those raw fetches
with the proper SDK/helper calls (use sdk.api.eth.getBalance for Ethereum, the
RPC helper pattern from projects/helper/chain/near.js for NEAR, and
`@solana/web3.js` connection helpers like getSolBalanceFromStakePool for Solana),
add null-checks/validation around RPC responses before accessing properties
(e.g., guard data.result / data.result.amount / data.result.value), and
implement retry/timeout/fallback logic consistent with the NEAR helper; ensure
the final balances are summed via sdk.util.sumSingleBalance (retain token format
like `ethereum:${ZeroAddress?.toLowerCase()}`) and surface/log RPC errors
instead of throwing unhandled exceptions.
projects/verified/index.js
Outdated
| const token = `ethereum:${ZeroAddress?.toLowerCase()}`; | ||
| sdk.util.sumSingleBalance(balances, token, Number(data.result)); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, let's examine the specific file and lines mentioned
echo "=== Reading projects/verified/index.js ==="
wc -l projects/verified/index.js
echo ""
echo "=== Lines 180-200 (around line 190-191) ==="
sed -n '180,200p' projects/verified/index.js | cat -n
echo ""
echo "=== Lines 225-245 (around line 233-234) ==="
sed -n '225,245p' projects/verified/index.js | cat -n
echo ""
echo "=== Lines 250-270 (around line 258-259) ==="
sed -n '250,270p' projects/verified/index.js | cat -nRepository: DefiLlama/DefiLlama-Adapters
Length of output: 2197
🏁 Script executed:
#!/bin/bash
# Search for how other adapters reference NEAR native token
echo "=== Examples of native NEAR token references ==="
rg -n 'near:' projects/ --type=js -A2 -B2 | grep -E '(near:0x|near:wrap|near:native|coingecko:near)' | head -20Repository: DefiLlama/DefiLlama-Adapters
Length of output: 120
🏁 Script executed:
#!/bin/bash
# Search for how other adapters reference Solana native token
echo "=== Examples of native Solana token references ==="
rg -n 'solana:' projects/ --type=js -A2 -B2 | grep -E '(solana:0x|solana:SOL|coingecko:solana|solana:native)' | head -20Repository: DefiLlama/DefiLlama-Adapters
Length of output: 122
🏁 Script executed:
#!/bin/bash
# Search for ZeroAddress usage across adapters
echo "=== ZeroAddress usage patterns ==="
rg -n 'ZeroAddress' projects/ --type=js -B2 -A2 | head -40Repository: DefiLlama/DefiLlama-Adapters
Length of output: 2135
🏁 Script executed:
#!/bin/bash
# Check for native token handling patterns in Ethereum adapters
echo "=== Ethereum native token patterns ==="
rg -n 'ethereum:0x0000000000000000000000000000000000000000|ethereum:0x0|null.*token|native.*eth' projects/ --type=js -i | head -20Repository: DefiLlama/DefiLlama-Adapters
Length of output: 2368
🏁 Script executed:
#!/bin/bash
# Search for SDK usage patterns with native token balances across chains
echo "=== Search for how SDK handles native tokens by chain ==="
rg -n 'sdk.util.sumSingleBalance|api.sumTokens|api.addToken' projects/ --type=js -B3 -A1 | head -60Repository: DefiLlama/DefiLlama-Adapters
Length of output: 3797
🏁 Script executed:
#!/bin/bash
# Look for NEAR and Solana specific adapter patterns
echo "=== NEAR adapters ==="
fd -e js 'near|nolus' projects/ --type f | head -10
echo ""
echo "=== Solana adapters ==="
fd -e js 'solana' projects/ --type f | head -10Repository: DefiLlama/DefiLlama-Adapters
Length of output: 431
🏁 Script executed:
#!/bin/bash
# Check how the verified adapter is structured - what's the intended usage
echo "=== Full context of verified/index.js around getEthBalance ==="
sed -n '175,195p' projects/verified/index.js | cat -n
echo ""
echo "=== Check imports and constants in verified/index.js ==="
head -20 projects/verified/index.js | cat -nRepository: DefiLlama/DefiLlama-Adapters
Length of output: 1585
🏁 Script executed:
#!/bin/bash
# Look for what the actual correct native token format should be
rg -n 'sumSingleBalance' projects/ --type=js -B2 -A2 -i | head -80Repository: DefiLlama/DefiLlama-Adapters
Length of output: 5102
🏁 Script executed:
#!/bin/bash
# Look for native token constant definitions
echo "=== Search for ADDRESSES.null and native token constants ==="
rg -n 'ADDRESSES.*null|NULL.*ADDRESS|NATIVE.*TOKEN|nullAddress' projects/helper/ --type=js | head -30Repository: DefiLlama/DefiLlama-Adapters
Length of output: 3231
🏁 Script executed:
#!/bin/bash
# Check apechainstake and other adapters that use nullAddress correctly
echo "=== apechainstake native token usage ==="
sed -n '1,25p' projects/apechainstake/index.js | cat -nRepository: DefiLlama/DefiLlama-Adapters
Length of output: 972
🏁 Script executed:
#!/antml:bash
# Look for how other adapters handle native token on Ethereum
echo "=== Ethereum native token examples ==="
rg -n 'nullAddress|ADDRESSES\.null' projects/boltz.js projects/eth-strategy/index.js -B2 -A2Repository: DefiLlama/DefiLlama-Adapters
Length of output: 748
Unresolved merge conflict and incorrect native token identifiers across chains.
The file has an unresolved merge conflict at lines 3–7. Additionally, all three balance-fetching functions (Ethereum, NEAR, Solana) incorrectly reference native tokens:
-
Lines 190-191:
ethereum:${ZeroAddress?.toLowerCase()}should use the SDK's native token format. Other Ethereum adapters useapi.sumTokens({ tokens: [ADDRESSES.null] })instead of the manualchain:addresskey format. -
Lines 233-234 & 258-259:
near:${ZeroAddress?.toLowerCase()}andsolana:${ZeroAddress?.toLowerCase()}are invalid. The EthereumZeroAddresshas no meaning on NEAR or Solana. Use the correct pattern for non-EVM chains: passnullAddressas the token with the chain name as the 4th parameter tosumSingleBalance, e.g.,sdk.util.sumSingleBalance(balances, nullAddress, amount, 'near')(seeapechainstake/index.js:16for example).
🤖 Prompt for AI Agents
In `@projects/verified/index.js` around lines 190 - 191, Resolve the leftover
merge conflict and fix native token handling: remove the manual
`ethereum:${ZeroAddress?.toLowerCase()}` style key and instead use the
SDK/native helpers when summing balances in the Ethereum, NEAR, and Solana
balance-fetching functions; for Ethereum prefer using api.sumTokens with
ADDRESSES.null or use sdk.util.sumSingleBalance(balances, ADDRESSES.null,
Number(data.result)) referencing ZeroAddress only in Ethereum adapters where
ADDRESSES.null is defined, and for NEAR/Solana replace
`near:${ZeroAddress?.toLowerCase()}` and `solana:${ZeroAddress?.toLowerCase()}`
with sdk.util.sumSingleBalance(balances, nullAddress, amount, 'near') and
sdk.util.sumSingleBalance(balances, nullAddress, amount, 'solana') respectively
(see functions that call sdk.util.sumSingleBalance and api.sumTokens for exact
placement).
projects/verified/index.js
Outdated
| let balances = {}; | ||
|
|
||
| const token = `ethereum:${ZeroAddress?.toLowerCase()}`; | ||
| sdk.util.sumSingleBalance(balances, token, Number(data.result)); |
There was a problem hiding this comment.
Precision loss when converting large integers with Number().
- Line 191:
Number(data.result)— ETH balance in wei (hex string) can exceedNumber.MAX_SAFE_INTEGER(~9 × 10¹⁵ wei ≈ 0.009 ETH). Any balance above ~0.009 ETH will silently lose precision. - Line 234:
Number(yoctoToNear(data.result.amount)) * 10 ** 18—yoctoToNearreturns a string representation of NEAR, which is then parsed as a float and multiplied by 10¹⁸. This introduces floating-point rounding errors. Also, NEAR uses 24 decimals natively, not 18 — so multiplying by 10¹⁸ doesn't reconstruct the original precision. - Line 259:
Number(data.result.value)— Solana balance in lamports (9 decimals) is less likely to overflow but still risky for large balances.
Use BigInt or string-based arithmetic throughout, or leverage the SDK's balance utilities which handle this correctly.
Also applies to: 234-234, 259-259
🤖 Prompt for AI Agents
In `@projects/verified/index.js` at line 191, Replace unsafe Number(...)
conversions and floating-point reconstruction with integer-safe handling: stop
passing Number(data.result) to sdk.util.sumSingleBalance and instead parse
hex/decimal balances into BigInt (or use the SDK's integer/string balance
helpers) and supply the correctly scaled string/BigInt; for NEAR, avoid parsing
yoctoToNear to a float then multiplying by 10**18—work directly with yocto
(24-decimal) amounts or use a string-based big-number utility to convert to the
target unit; similarly replace Number(data.result.value) for Solana lamports
with BigInt/string arithmetic before calling sdk.util.sumSingleBalance so no
precision is lost.
| Object.keys(chainsConfig).forEach((chain) => { | ||
| if(chainsConfig[chain]?.subgraphUrl) { | ||
| module.exports[chain] = { | ||
| tvl: getChainTvls(chain) | ||
| }; | ||
| }else if(chainsConfig[chain]?.address) { | ||
| module.exports[chain] = { | ||
| tvl: getAddressTvl(chain, chainsConfig[chain]?.address), | ||
| }; | ||
| } | ||
|
|
There was a problem hiding this comment.
Ethereum gets double-counted: subgraph TVL + address balance are both applied.
For Ethereum, chainsConfig has both subgraphUrl and address. The module.exports loop (line 294) checks subgraphUrl first, so it calls getChainTvls('ethereum'). Inside getChainTvls (lines 162–168), the code also checks chainsConfig[chain].address and merges the address balance. This means Ethereum TVL includes both subgraph data and the custodial wallet balance.
Meanwhile, the else if branch (line 298) for address-only chains is never reached for Ethereum. This dual path is confusing and may lead to unintended double-counting if the custodial wallet funds are the same as those tracked by the subgraph. Please verify this is intentional and document it clearly if so.
🧰 Tools
🪛 Biome (2.3.13)
[error] 293-293: Expected a JSX attribute but instead found '.'.
Expected a JSX attribute here.
(parse)
[error] 293-293: Expected a JSX attribute but instead found '('.
Expected a JSX attribute here.
(parse)
[error] 293-293: Expected a JSX attribute but instead found ').'.
Expected a JSX attribute here.
(parse)
[error] 293-293: Expected a JSX attribute but instead found '(('.
Expected a JSX attribute here.
(parse)
[error] 293-293: Expected a JSX attribute but instead found ') =>'.
Expected a JSX attribute here.
(parse)
[error] 294-294: expected ... but instead found if
Remove if
(parse)
[error] 294-294: Expected a JSX attribute but instead found '('.
Expected a JSX attribute here.
(parse)
[error] 294-294: Expected a JSX attribute but instead found '['.
Expected a JSX attribute here.
(parse)
[error] 294-294: Expected a JSX attribute but instead found ']?.'.
Expected a JSX attribute here.
(parse)
[error] 294-294: Expected a JSX attribute but instead found ')'.
Expected a JSX attribute here.
(parse)
[error] 295-295: expected ... but instead found module
Remove module
(parse)
[error] 297-297: expected } but instead found ;
Remove ;
(parse)
[error] 298-298: Unexpected token. Did you mean {'}'} or }?
(parse)
[error] 301-301: expected } but instead found ;
Remove ;
(parse)
[error] 302-302: Unexpected token. Did you mean {'}'} or }?
(parse)
[error] 300-300: This variable is used before its declaration.
The variable is declared here:
(lint/correctness/noInvalidUseBeforeDeclaration)
🤖 Prompt for AI Agents
In `@projects/verified/index.js` around lines 293 - 303, chainsConfig entries with
both subgraphUrl and address are causing double-counting because the
module.exports loop uses getChainTvls(chain) for subgraph-enabled chains while
getChainTvls itself also merges chainsConfig[chain].address balances; update the
logic so only one source is applied: either remove/disable the address-merge
inside getChainTvls(chain) when chainsConfig[chain].subgraphUrl exists, or
change the module.exports loop to prefer address-only (call getAddressTvl) when
both are present; modify the code paths around chainsConfig, getChainTvls, and
getAddressTvl to make the behavior explicit (or add a config flag like
includeAddressWithSubgraph) and document the chosen behavior.
feat: solana, near chains fix
|
The adapter at projects/verified exports TVL: |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@projects/verified/index.js`:
- Around line 112-116: The addBalance function calls
ethers.parseUnits(amount?.toString(), decimals) which will throw if amount is
null/undefined; update addBalance (or its call sites) to guard amount and treat
missing values as zero: ensure amount is normalized before parseUnits (e.g.,
default to "0" when amount is null/undefined) or early-return when amount is
falsy, then continue to compute token and call
sdk.util.sumSingleBalance(balances, token, scaledAmount) only with a valid
scaledAmount; modify the addBalance implementation that references
ethers.parseUnits, token, chain, decimals, balances, and
sdk.util.sumSingleBalance accordingly.
- Around line 197-201: The code builds the wrong token id and loses precision by
converting yocto→NEAR via Number and parseEther; replace the manual
token/formatting with the NEAR helper's sumSingleBalance which knows the
tokenMapping and 24-decimal handling: stop creating token =
`near:${nullAddress}` and stop using
yoctoToNear/Number/.toFixed/ethers.parseEther; instead call the NEAR helper's
sumSingleBalance (same utility used by other adapters) passing balances, the
correct token id 'wrap.near' (or the helper's mapped id), and the raw yocto
amount from view_account so the helper performs the division by 24 decimals
without floating-point precision loss.
🧹 Nitpick comments (1)
projects/verified/index.js (1)
152-247: Inconsistent indentation throughout the balance-fetching functions.The indentation varies between 0, 1, 2, and 3 spaces across
getEthBalance,getNearBalance, andgetSolBalance. This makes the control flow hard to follow and increases the chance of bugs hiding in plain sight. Consider running a formatter (e.g., Prettier) to normalize indentation.
| const addBalance = (amount, tokenAddress) => { | ||
| const token = `${chain}:${tokenAddress.toLowerCase()}`; | ||
| const scaledAmount = Number(amount) * (10 ** decimals); | ||
| const scaledAmount = ethers.parseUnits(amount?.toString(), decimals); | ||
| sdk.util.sumSingleBalance(balances, token, scaledAmount); | ||
| }; |
There was a problem hiding this comment.
ethers.parseUnits will throw on null/undefined amounts.
If amount is null or undefined (e.g., a subscription with no subscription field), amount?.toString() yields "undefined", and ethers.parseUnits("undefined", decimals) will throw. Add a guard before calling addBalance, or default amount to "0".
Proposed fix
const addBalance = (amount, tokenAddress) => {
+ if (!amount) return;
const token = `${chain}:${tokenAddress.toLowerCase()}`;
const scaledAmount = ethers.parseUnits(amount?.toString(), decimals);
sdk.util.sumSingleBalance(balances, token, scaledAmount);
};📝 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.
| const addBalance = (amount, tokenAddress) => { | |
| const token = `${chain}:${tokenAddress.toLowerCase()}`; | |
| const scaledAmount = Number(amount) * (10 ** decimals); | |
| const scaledAmount = ethers.parseUnits(amount?.toString(), decimals); | |
| sdk.util.sumSingleBalance(balances, token, scaledAmount); | |
| }; | |
| const addBalance = (amount, tokenAddress) => { | |
| if (!amount) return; | |
| const token = `${chain}:${tokenAddress.toLowerCase()}`; | |
| const scaledAmount = ethers.parseUnits(amount?.toString(), decimals); | |
| sdk.util.sumSingleBalance(balances, token, scaledAmount); | |
| }; |
🤖 Prompt for AI Agents
In `@projects/verified/index.js` around lines 112 - 116, The addBalance function
calls ethers.parseUnits(amount?.toString(), decimals) which will throw if amount
is null/undefined; update addBalance (or its call sites) to guard amount and
treat missing values as zero: ensure amount is normalized before parseUnits
(e.g., default to "0" when amount is null/undefined) or early-return when amount
is falsy, then continue to compute token and call
sdk.util.sumSingleBalance(balances, token, scaledAmount) only with a valid
scaledAmount; modify the addBalance implementation that references
ethers.parseUnits, token, chain, decimals, balances, and
sdk.util.sumSingleBalance accordingly.
| const nearBalanceRes = await view_account(address) | ||
|
|
||
| const token = `near:${nullAddress?.toLowerCase()}`; | ||
| const formattedBalance = ethers.parseEther(Number(yoctoToNear(nearBalanceRes?.amount))?.toFixed(18)); //using yocto(^24) gives wrong unit as wei(^18) seems to be the highest unit | ||
| sdk.util.sumSingleBalance(balances, token, formattedBalance); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's see the actual code in the file to confirm the lines and context
head -220 projects/verified/index.js | tail -40Repository: DefiLlama/DefiLlama-Adapters
Length of output: 1081
🏁 Script executed:
# Find nullAddress definition
rg -n 'nullAddress\s*=' projects/verified/index.js -B2 -A2Repository: DefiLlama/DefiLlama-Adapters
Length of output: 54
🏁 Script executed:
# Check for nullAddress in helper files
rg -n 'nullAddress' projects/ --type=js -B2 -A2 | head -30Repository: DefiLlama/DefiLlama-Adapters
Length of output: 1939
🏁 Script executed:
# Look for how NEAR tokens are referenced elsewhere in the verified adapter
rg -n 'near:' projects/verified/index.js -B2 -A2Repository: DefiLlama/DefiLlama-Adapters
Length of output: 647
🏁 Script executed:
# Check how other adapters handle NEAR native token
rg -n 'sumSingleBalance.*near' projects/ --type=js -B2 -A2 | head -40Repository: DefiLlama/DefiLlama-Adapters
Length of output: 2265
🏁 Script executed:
# Look at yoctoToNear function definition
rg -n 'yoctoToNear' projects/ --type=js -B2 -A5 | head -50Repository: DefiLlama/DefiLlama-Adapters
Length of output: 1177
🏁 Script executed:
# Find where nullAddress is defined
rg -n 'const nullAddress|export.*nullAddress' projects/ --type=js -B2 -A2 | head -40Repository: DefiLlama/DefiLlama-Adapters
Length of output: 2198
🏁 Script executed:
# Check the helper files to understand nullAddress value
cat projects/helper/tokenMapping.js | head -50Repository: DefiLlama/DefiLlama-Adapters
Length of output: 2759
🏁 Script executed:
# Look at how rhealst.js uses NEAR tokens more broadly
cat projects/rhealst.js | grep -A5 -B5 'wrap.near\|sumSingleBalance'Repository: DefiLlama/DefiLlama-Adapters
Length of output: 536
🏁 Script executed:
# Check if there are other NEAR balance examples in verified adapter or similar adapters
rg -n 'getNearBalance\|getSolBalance' projects/verified/index.js -A20 | head -60Repository: DefiLlama/DefiLlama-Adapters
Length of output: 54
🏁 Script executed:
# Verify how sumSingleBalance is typically called for NEAR
rg -n 'sumSingleBalance.*near' projects/ --type=js -A1 -B1 | head -50Repository: DefiLlama/DefiLlama-Adapters
Length of output: 2913
🏁 Script executed:
# Check what ADDRESSES.null resolves to in coreAssets.json
rg -n '"null"' projects/helper/coreAssets.json | head -5Repository: DefiLlama/DefiLlama-Adapters
Length of output: 316
🏁 Script executed:
# See the actual structure of coreAssets for null address
cat projects/helper/coreAssets.json | head -100Repository: DefiLlama/DefiLlama-Adapters
Length of output: 5445
🏁 Script executed:
# Check how verified/index.js imports things
head -30 projects/verified/index.jsRepository: DefiLlama/DefiLlama-Adapters
Length of output: 1045
🏁 Script executed:
# Look at the complete getNearBalance and related functions in context
sed -n '170,215p' projects/verified/index.jsRepository: DefiLlama/DefiLlama-Adapters
Length of output: 1205
🏁 Script executed:
# Check if there's any NEAR-specific documentation or config in verified adapter
cat projects/verified/index.js | grep -i 'near' -A2 -B2 | head -80Repository: DefiLlama/DefiLlama-Adapters
Length of output: 1484
🏁 Script executed:
# Verify what the correct NEAR token identifier should be
rg -n 'coingecko:near|wrap\.near' projects/ --type=js -B1 -A1 | head -30Repository: DefiLlama/DefiLlama-Adapters
Length of output: 1791
🏁 Script executed:
# Check how the near helper module exports sumSingleBalance
grep -A 10 'function sumSingleBalance\|const sumSingleBalance\|exports.sumSingleBalance' projects/helper/chain/near.jsRepository: DefiLlama/DefiLlama-Adapters
Length of output: 328
🏁 Script executed:
# Check if there's documentation or examples of how to properly add NEAR native balance
rg -n 'getNearBalance\|get.*near.*balance' projects/ --type=js -A5 | grep -E '(sumSingleBalance|token|near)' | head -20Repository: DefiLlama/DefiLlama-Adapters
Length of output: 54
🏁 Script executed:
# Check the tokenMapping for NEAR to see what valid identifiers are
rg -n 'tokenMapping' projects/helper/chain/near.js -A 50 | head -100Repository: DefiLlama/DefiLlama-Adapters
Length of output: 4382
🏁 Script executed:
# Look at how tonic handles NATIVE_NEAR in practice
sed -n '1,50p' projects/tonic/index.jsRepository: DefiLlama/DefiLlama-Adapters
Length of output: 1880
🏁 Script executed:
# Check spin's usage of NATIVE_NEAR
sed -n '1,50p' projects/spin/index.jsRepository: DefiLlama/DefiLlama-Adapters
Length of output: 1370
🏁 Script executed:
# Verify the coreAssets to see if there's a NEAR entry
rg -n '"near"' projects/helper/coreAssets.json | head -20Repository: DefiLlama/DefiLlama-Adapters
Length of output: 87
🏁 Script executed:
# Double-check that 'near:near' doesn't exist in the codebase
rg -n 'near:near' projects/ --type=jsRepository: DefiLlama/DefiLlama-Adapters
Length of output: 54
🏁 Script executed:
# Confirm the pattern - verify wrap.near is the standard for accounting NEAR balance
rg -n 'sumSingleBalance.*wrap\.near' projects/ --type=js -B2 -A2Repository: DefiLlama/DefiLlama-Adapters
Length of output: 726
🏁 Script executed:
# Check if code should be using the near helper's sumSingleBalance instead of sdk.util
rg -n 'const.*sumSingleBalance.*=.*require.*near' projects/ --type=js | head -10Repository: DefiLlama/DefiLlama-Adapters
Length of output: 1151
Fix NEAR token identifier and avoid precision loss in balance conversion.
Two issues:
-
Wrong token identifier —
near:${nullAddress}uses an EVM address (0x0000…0000), not a NEAR token. This won't match any entry in the NEAR helper's tokenMapping. Other NEAR adapters use'wrap.near'for native NEAR accounting (seerhealst.js,tonic.js,octopus-network.js). -
Precision loss from float conversion — Converting yocto (24 decimals) to NEAR via
Number(yoctoToNear(...))introduces floating-point imprecision for large balances. The chainyocto→NEAR(string)→Number(float)→.toFixed(18)→parseEtheris unnecessarily complex and lossy.
Solution: Import and use the NEAR helper's sumSingleBalance (which handles tokenMapping lookup and decimal conversion), pass the raw yocto amount directly, and use the correct token identifier:
-const sdk = require('@defillama/sdk');
-const { ethers } = require("ethers");
-const { nullAddress } = require("../helper/tokenMapping");
-const { view_account } = require("../helper/chain/near");
+const { view_account, sumSingleBalance } = require("../helper/chain/near");
const getNearBalance = (address) => {
return async (_, __, ___) => {
let balances = {};
try {
const nearBalanceRes = await view_account(address)
- const token = `near:${nullAddress?.toLowerCase()}`;
- const formattedBalance = ethers.parseEther(Number(yoctoToNear(nearBalanceRes?.amount))?.toFixed(18));
- sdk.util.sumSingleBalance(balances, token, formattedBalance);
+ sumSingleBalance(balances, 'wrap.near', nearBalanceRes?.amount);
} catch (err) {
console.warn("get Near balance failed with error: ", err?.message || err)
}
return balances;
}
}The near helper's sumSingleBalance automatically divides by the token's 24-decimal precision defined in tokenMapping.
🤖 Prompt for AI Agents
In `@projects/verified/index.js` around lines 197 - 201, The code builds the wrong
token id and loses precision by converting yocto→NEAR via Number and parseEther;
replace the manual token/formatting with the NEAR helper's sumSingleBalance
which knows the tokenMapping and 24-decimal handling: stop creating token =
`near:${nullAddress}` and stop using
yoctoToNear/Number/.toFixed/ethers.parseEther; instead call the NEAR helper's
sumSingleBalance (same utility used by other adapters) passing balances, the
correct token id 'wrap.near' (or the helper's mapped id), and the raw yocto
amount from view_account so the helper performs the division by 24 decimals
without floating-point precision loss.
NOTE
Please enable "Allow edits by maintainers" while putting up the PR.
package-lock.jsonfile as part of your changes, we use lockfileVersion 2, and most use v1 and using that messes up our CIName (to be shown on DefiLlama): Verified Network
Twitter Link: https://x.com/veridefi
List of audit links if any:
Website Link: https://www.verified.network
Logo (High resolution, will be shown with rounded borders):
Current TVL: $3.34 million
Treasury Addresses (if the protocol has treasury)
Chain: NEAR, Ethereum
Coingecko ID (so your TVL can appear on Coingecko, leave empty if not listed): (https://api.coingecko.com/api/v3/coins/list)
Coinmarketcap ID (so your TVL can appear on Coinmarketcap, leave empty if not listed): (https://api.coinmarketcap.com/data-api/v3/map/all?listing_status=active,inactive,untracked&start=1&limit=10000)
Short Description (to be shown on DefiLlama): Verified Network is decentralized, global financial infrastructure for issuing, distributing and servicing tokenized securities.
Token address and ticker if any:
Category (full list at https://defillama.com/categories) *Please choose only one: RWA
Oracle Provider(s): Specify the oracle(s) used (e.g., Chainlink, Band, API3, TWAP, etc.):
Implementation Details: Briefly describe how the oracle is integrated into your project:
Documentation/Proof: Provide links to documentation or any other resources that verify the oracle's usage:
forkedFrom (Does your project originate from another project):
methodology (what is being counted as tvl, how is tvl being calculated):
Github org/user (Optional, if your code is open source, we can track activity):
Does this project have a referral program?
Summary by CodeRabbit
New Features
Improvements