From 627876b42f06d076ecb1a1710d0f8fafc021c5c7 Mon Sep 17 00:00:00 2001 From: Yehia Tarek Date: Fri, 17 Jan 2025 19:27:19 +0200 Subject: [PATCH] Add LibreCapital tvl calculation --- projects/libre-capital/index.js | 108 ++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 projects/libre-capital/index.js diff --git a/projects/libre-capital/index.js b/projects/libre-capital/index.js new file mode 100644 index 0000000000..b891c77f85 --- /dev/null +++ b/projects/libre-capital/index.js @@ -0,0 +1,108 @@ +const sdk = require("@defillama/sdk"); +const { queryContract: queryContractCosmos } = require("../helper/chain/cosmos"); +const { fetchURL } = require("../helper/utils"); + +const NAV_API_URL = "https://nav.dev.librecapital.com/funds"; + +const RECEIPT_TOKENS = { + polygon: { + UMA: { + address: '0xcf2Ca1B21e6f5dA7A2744f89667dE4E450791C79', + decimals: 18, + underlying: 'security-token', + fundName:'USD I Money Market, a sub-fund of Libre SAF VCC' + }, + BHMA: { + address: '0xcc777c52ee9Ee5A57965a8E56F06211Fad34Fb3B', + decimals: 18, + underlying: 'security-token', + fundName:'BH Master Fund Access, a sub-fund of Libre SAF VCC' + } + }, + injective: { + UMA: { + address: 'inj1eh6h6vllrvtl6qyq77cv5uwy0hw6e6d8jy4pxy', + decimals: 18, + underlying: 'security-token', + fundName:'USD I Money Market, a sub-fund of Libre SAF VCC' + } + } +} + +async function getFundPrices() { + const { data: navData } = await fetchURL(NAV_API_URL); + const priceMap = {}; + navData.forEach(fund => { + priceMap[fund.fundName] = fund.priceLocal; + }); + return priceMap; +} + +async function polygonTvl({ polygon: block137 }) { + const balances = {} + let totalTvl = 0; + const fundPrices = await getFundPrices(); + + // Get total supply of both receipt tokens + const supplies = await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: Object.values(RECEIPT_TOKENS.polygon).map(i => ({ target: i.address })), + chain: 'polygon', + block: block137, + }) + + + // Map each token's total supply to represent RWA TVL + supplies.output.forEach((supply, i) => { + const token = Object.values(RECEIPT_TOKENS.polygon)[i] + const balance = supply.output; + const price = fundPrices[token.fundName] || 1; + + // Convert balance to human readable and multiply by price + const adjustedBalance = Number(balance) / (10 ** token.decimals); + const valueUSD = adjustedBalance * price; + + totalTvl += valueUSD; + }) + + // Return the total value in the format DeFiLlama expects + balances['usd-coin'] = totalTvl; + return balances; +} + +async function injectiveTvl() { + const balances = {} + let totalTvl = 0; + const fundPrices = await getFundPrices(); + + // Query total supply from Injective contract + const supply = await queryContractCosmos({ + contract: RECEIPT_TOKENS.injective.UMA.address, + chain: 'injective', + data: { + token_info: {} + } + }) + + if (supply?.total_supply) { + const token = RECEIPT_TOKENS.injective.UMA; + const balance = supply.total_supply; + const price = fundPrices[token.fundName] || 1; + + // Convert balance to human readable and multiply by price + const adjustedBalance = Number(balance) / (10 ** token.decimals); + const valueUSD = adjustedBalance * price; + + totalTvl += valueUSD; + } + + // Return the total value in the format DeFiLlama expects + balances['usd-coin'] = totalTvl; + return balances; +} + +module.exports = { + methodology: "TVL represents the total value of institutional funds represented by UMA, BHMA and UMA receipt tokens on Polygon and Injective. The value is calculated by multiplying the total supply of receipt tokens by their respective NAV prices, denominated in their underlying stablecoin value", + polygon: { tvl: polygonTvl }, + injective: { tvl: injectiveTvl } +} \ No newline at end of file