Skip to content
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 73 additions & 19 deletions projects/surf-liquid/index.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,78 @@
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);
Copy link
Contributor

Choose a reason for hiding this comment

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

please move the SURF token tracking back under the staking export

Copy link
Author

Choose a reason for hiding this comment

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

Done, also when will numbers be updated and depreciation tag removed?

}

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.",
hallmarks: [["2025-11-30", "V3 factory launched"]],
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,
},
};
Loading