From f124e99a19f1747f3a2eb3960363d1259b886a05 Mon Sep 17 00:00:00 2001 From: rohansingh4 Date: Wed, 11 Mar 2026 19:05:51 +0530 Subject: [PATCH 1/4] Update surf-liquid TVL adapter with V2/V3 vault support and staking - Enumerate V2 vaults via factory getTotalVaults/getVaultInfo - Discover V3 vaults via VaultDeployed event logs - Count Morpho ERC-4626 vault share positions as TVL - Add staking: SURF staked + CreatorBid subscriptions --- projects/surf-liquid/index.js | 91 +++++++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 19 deletions(-) diff --git a/projects/surf-liquid/index.js b/projects/surf-liquid/index.js index 7a71f05cd48..26ac6eb0409 100644 --- a/projects/surf-liquid/index.js +++ b/projects/surf-liquid/index.js @@ -1,24 +1,77 @@ -const target = "0x1D283b668F947E03E8ac8ce8DA5505020434ea0E"; +const V2_FACTORY = "0x1D283b668F947E03E8ac8ce8DA5505020434ea0E"; +const V3_FACTORY = "0xf1d64dee9f8e109362309a4bfbb523c8e54fa1aa"; +const SURF_STAKING = "0xB0fDFc081310A5914c2d2c97e7582F4De12FA9d6"; +const SURF_TOKEN = "0xcdca2eaae4a8a6b83d7a3589946c2301040dafbf"; +const USDC = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"; +const WETH = "0x4200000000000000000000000000000000000006"; +const CBBTC = "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf"; +const ASSETS = [USDC, WETH, CBBTC]; +const ZERO_ADDR = "0x0000000000000000000000000000000000000000"; + +async function tvl(api) { + const tokensAndOwners = []; + + // V2 Vaults: enumerate via factory, read Morpho ERC-4626 positions + const totalV2 = await api.call({ abi: "uint256:getTotalVaults", target: V2_FACTORY }); + const v2Infos = await api.multiCall({ + abi: "function getVaultInfo(uint256) view returns (address, address, address, uint256, bytes32, uint256)", + calls: [...Array(Number(totalV2)).keys()].map((i) => ({ target: V2_FACTORY, params: [i] })), + }); + const v2Owners = v2Infos.map((info) => info[0]); + const v2MorphoVaults = await api.multiCall({ + abi: "address:currentVault", + calls: v2Owners.map((target) => ({ target })), + }); + for (let i = 0; i < v2Owners.length; i++) { + if (v2MorphoVaults[i] !== ZERO_ADDR) { + tokensAndOwners.push([v2MorphoVaults[i], v2Owners[i]]); + } + } + + // V3 Vaults: discover via event logs, read Morpho ERC-4626 positions per asset + const currentBlock = api.block || await api.getBlock(); + const v3Logs = await api.getLogs({ + target: V3_FACTORY, + eventAbi: "event VaultDeployed(address indexed vaultAddress, address indexed owner, address indexed pool, bytes32 marketId, uint256 chainId)", + onlyArgs: true, + fromBlock: 38856207, + toBlock: currentBlock, + }); + const v3Vaults = v3Logs.map((l) => l.vaultAddress); + + for (const asset of ASSETS) { + const morphoVaults = await api.multiCall({ + abi: "function assetToVault(address) view returns (address)", + calls: v3Vaults.map((vault) => ({ target: vault, params: [asset] })), + }); + for (let i = 0; i < v3Vaults.length; i++) { + if (morphoVaults[i] && morphoVaults[i] !== ZERO_ADDR) { + tokensAndOwners.push([morphoVaults[i], v3Vaults[i]]); + } + } + } + + await api.sumTokens({ tokensAndOwners }); +} + +async function staking(api) { + // SURF staking contract + const totalStaked = await api.call({ abi: "uint256:totalStaked", target: SURF_STAKING }); + api.add(SURF_TOKEN, totalStaked); + + // CreatorBid SURF subscriptions (SURF locked in the token contract) + const subscribed = await api.call({ + abi: "function balanceOf(address) view returns (uint256)", + target: SURF_TOKEN, + params: [SURF_TOKEN], + }); + api.add(SURF_TOKEN, subscribed); +} module.exports = { - methodology: "Counts the morpho deposits of each Surf Liquid vault.", + methodology: "TVL counts Morpho vault deposits across V2 and V3 Surf Liquid vaults. Staking includes SURF staked and SURF subscriptions.", base: { - tvl: async (api) => { - const vaults = await api.call({ abi: "uint256:getTotalVaults", target }); - const vaultInfos = await api.multiCall({ - abi: "function getVaultInfo(uint256) view returns (address, address, address, uint256, bytes32, uint256)", - calls: [...Array(Number(vaults)).keys()].map((i) => ({ target, params: [i] })), - }); - const owners = vaultInfos.map(info => info[0]) - const morphoVaults = await api.multiCall({ - abi: "address:currentVault", - calls: owners.map(target => ({ target })) - }) - - await api.sumTokens({ - tokens: [...new Set(morphoVaults)], - owners - }) - }, + tvl, + staking, }, }; From e90db2a899d3b6050b7a5444f982490dab490637 Mon Sep 17 00:00:00 2001 From: rohansingh4 Date: Thu, 12 Mar 2026 16:13:55 +0530 Subject: [PATCH 2/4] Merge staking into TVL for a single combined metric Include SURF staking and CreatorBid subscriptions directly in the tvl function instead of a separate staking category. --- projects/surf-liquid/index.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/projects/surf-liquid/index.js b/projects/surf-liquid/index.js index 26ac6eb0409..6d928fe0d5a 100644 --- a/projects/surf-liquid/index.js +++ b/projects/surf-liquid/index.js @@ -52,9 +52,7 @@ async function tvl(api) { } await api.sumTokens({ tokensAndOwners }); -} -async function staking(api) { // SURF staking contract const totalStaked = await api.call({ abi: "uint256:totalStaked", target: SURF_STAKING }); api.add(SURF_TOKEN, totalStaked); @@ -69,9 +67,8 @@ async function staking(api) { } module.exports = { - methodology: "TVL counts Morpho vault deposits across V2 and V3 Surf Liquid vaults. Staking includes SURF staked and SURF subscriptions.", + methodology: "TVL counts Morpho vault deposits across V2 and V3 Surf Liquid vaults, SURF staked, and CreatorBid SURF subscriptions.", base: { tvl, - staking, }, }; From ccfb2804a25fac7bfcd2f951e64e793c1a2b9f21 Mon Sep 17 00:00:00 2001 From: rohansingh4 Date: Fri, 13 Mar 2026 10:46:36 +0530 Subject: [PATCH 3/4] Move SURF staking back to separate export, add V3 hallmark Per reviewer feedback: - Move SURF staking + CreatorBid subscriptions back under staking export - Add hallmarks entry for V3 factory launch (2025-11-30) to explain TVL spike --- projects/surf-liquid/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/projects/surf-liquid/index.js b/projects/surf-liquid/index.js index 6d928fe0d5a..abb0bf25353 100644 --- a/projects/surf-liquid/index.js +++ b/projects/surf-liquid/index.js @@ -52,7 +52,9 @@ async function tvl(api) { } await api.sumTokens({ tokensAndOwners }); +} +async function staking(api) { // SURF staking contract const totalStaked = await api.call({ abi: "uint256:totalStaked", target: SURF_STAKING }); api.add(SURF_TOKEN, totalStaked); @@ -67,8 +69,10 @@ async function tvl(api) { } module.exports = { - methodology: "TVL counts Morpho vault deposits across V2 and V3 Surf Liquid vaults, SURF staked, and CreatorBid SURF subscriptions.", + methodology: "TVL counts Morpho vault deposits across V2 and V3 Surf Liquid vaults. Staking includes SURF staked and SURF subscriptions.", + hallmarks: [["2025-11-30", "V3 factory launched"]], base: { tvl, + staking, }, }; From 241a0d740e9f6dae7cee45bcd7ae0dda8d9008c9 Mon Sep 17 00:00:00 2001 From: rohansingh4 Date: Tue, 24 Mar 2026 14:48:10 +0530 Subject: [PATCH 4/4] Add doublecounted/misrepresentedTokens flags, harden V2 guard - Mark adapter as doublecounted and misrepresentedTokens since TVL counts Morpho ERC-4626 vault shares (vault-in-vault) - Harden V2 loop to check both owner and vault are truthy before pushing --- projects/surf-liquid/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/projects/surf-liquid/index.js b/projects/surf-liquid/index.js index abb0bf25353..c27f2cba968 100644 --- a/projects/surf-liquid/index.js +++ b/projects/surf-liquid/index.js @@ -23,7 +23,7 @@ async function tvl(api) { calls: v2Owners.map((target) => ({ target })), }); for (let i = 0; i < v2Owners.length; i++) { - if (v2MorphoVaults[i] !== ZERO_ADDR) { + if (v2Owners[i] && v2Owners[i] !== ZERO_ADDR && v2MorphoVaults[i] && v2MorphoVaults[i] !== ZERO_ADDR) { tokensAndOwners.push([v2MorphoVaults[i], v2Owners[i]]); } } @@ -70,6 +70,8 @@ async function staking(api) { module.exports = { methodology: "TVL counts Morpho vault deposits across V2 and V3 Surf Liquid vaults. Staking includes SURF staked and SURF subscriptions.", + doublecounted: true, + misrepresentedTokens: true, hallmarks: [["2025-11-30", "V3 factory launched"]], base: { tvl,