From c266231699995ce49b39de9f2b84f7b120e00dd3 Mon Sep 17 00:00:00 2001 From: Kiril Ivanov Date: Fri, 14 Nov 2025 15:42:08 +0100 Subject: [PATCH 1/2] Add Kasu TVL adapter --- projects/kasu/index.js | 69 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 projects/kasu/index.js diff --git a/projects/kasu/index.js b/projects/kasu/index.js new file mode 100644 index 00000000000..c98088551ec --- /dev/null +++ b/projects/kasu/index.js @@ -0,0 +1,69 @@ +const { cachedGraphQuery } = require('../helper/cache') +const ADDRESSES = require('../helper/coreAssets.json') + +const GRAPH_URLS = { + base: { + uri: 'https://subgraph.satsuma-prod.com/3ed46ea711d3/kasu-finance--314476/kasu-base/api', + query: `{ + lendingPools (where:{isStopped: false}){ + id + balance + } + }` + }, + plume: { + uri: 'https://api.goldsky.com/api/public/project_cm9t3064xeuyn01tgctdo3c17/subgraphs/kasu-plume/prod/gn', + query: `{ + lendingPools { + id + balance + } + }` + } +}; + +const CHAIN_ASSET = { + base: { + asset: ADDRESSES.base.USDC, + decimals: 6 + }, + plume: { + asset: ADDRESSES.plume_mainnet.pUSD, + decimals: 6 + }, +} + +function offChainPoolTVL(api, poolAddress) { + return api.call({ + abi: 'function externalTVLOfPool(address) view returns (uint256)', + target: '0x662379FEBb3e4F91400B5f7d4f7F7ce4699F3c9F', + params: [poolAddress], + }); +} + +function tvl(chain) { + return async (api) => { + const result = await cachedGraphQuery('kasu/' + chain, GRAPH_URLS[chain].uri, GRAPH_URLS[chain].query); + const tvl = result.lendingPools.map((pool => pool.balance)).reduce((a,b) => a + b * (10 ** CHAIN_ASSET[chain].decimals), 0); + let externalTvl = 0; + if (chain === 'base') { + //add externally managed TVL on Base + const externalTvlResults = await Promise.all( + result.lendingPools.map(async (pool) => Number(await offChainPoolTVL(api, pool.id))) + ); + externalTvl = externalTvlResults.reduce((a, b) => a + b || 0, 0); + } + api.addTokens([CHAIN_ASSET[chain].asset], [tvl + externalTvl]); + return api.getBalances() + }; +} + +module.exports = { + methodology: 'Count all assets deposited to Kasu Lending Pools', + base: { + tvl: tvl('base'), + }, + plume: { + tvl: tvl('plume'), + }, +}; From 948e7bef887f76872694d3bf87819e46ea9de739 Mon Sep 17 00:00:00 2001 From: Kiril Ivanov Date: Tue, 18 Nov 2025 10:56:18 +0100 Subject: [PATCH 2/2] Using api.multiCall now --- projects/kasu/index.js | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/projects/kasu/index.js b/projects/kasu/index.js index c98088551ec..62296dcc849 100644 --- a/projects/kasu/index.js +++ b/projects/kasu/index.js @@ -33,14 +33,6 @@ const CHAIN_ASSET = { }, } -function offChainPoolTVL(api, poolAddress) { - return api.call({ - abi: 'function externalTVLOfPool(address) view returns (uint256)', - target: '0x662379FEBb3e4F91400B5f7d4f7F7ce4699F3c9F', - params: [poolAddress], - }); -} - function tvl(chain) { return async (api) => { const result = await cachedGraphQuery('kasu/' + chain, GRAPH_URLS[chain].uri, GRAPH_URLS[chain].query); @@ -48,10 +40,14 @@ function tvl(chain) { let externalTvl = 0; if (chain === 'base') { //add externally managed TVL on Base - const externalTvlResults = await Promise.all( - result.lendingPools.map(async (pool) => Number(await offChainPoolTVL(api, pool.id))) - ); - externalTvl = externalTvlResults.reduce((a, b) => a + b || 0, 0); + const externalTvlResults = await api.multiCall({ + abi: 'function externalTVLOfPool(address) view returns (uint256)', + calls: result.lendingPools.map(pool => ({ + target: '0x662379FEBb3e4F91400B5f7d4f7F7ce4699F3c9F', + params: [pool.id], + })), + }); + externalTvl = externalTvlResults.reduce((a, b) => a + Number(b || 0), 0); } api.addTokens([CHAIN_ASSET[chain].asset], [tvl + externalTvl]); return api.getBalances()