diff --git a/.env.dist b/.env.dist index 215fd94d06..f57268c78c 100644 --- a/.env.dist +++ b/.env.dist @@ -5,7 +5,7 @@ SUPABASE_VAULT_APY_TABLE_NAME=vault-apy-development SUPABASE_ASSET_PRICE_TABLE_NAME=asset-price-development SUPABASE_ASSET_TOTAL_APY_TABLE_NAME=asset-total-apy-development SUPABASE_ASSET_TVL_TABLE_NAME=asset-tvl-development -SUPABASE_ASSET_TOTAL_TVL_TABLE_NAME=test_ionic +SUPABASE_ASSET_TOTAL_TVL_TABLE_NAME=total-asset-tvl UPTIME_ASSET_PRICE_API= UPTIME_TOTAL_APY_API= UPTIME_TOTAL_HISTORY_APY_API= diff --git a/packages/functions/src/controllers/asset-tvl.ts b/packages/functions/src/controllers/asset-tvl.ts index 9f599e94ab..a3b7e7ca87 100644 --- a/packages/functions/src/controllers/asset-tvl.ts +++ b/packages/functions/src/controllers/asset-tvl.ts @@ -1,7 +1,7 @@ import { NativePricedIonicAsset, SupportedChains } from '@ionicprotocol/types'; import { functionsAlert } from '../alert'; import { environment, supabase } from '../config'; -import { IonicSdk, filterOnlyObjectProperties } from '@ionicprotocol/sdk'; +import { IonicSdk, erc20Abi, filterOnlyObjectProperties } from '@ionicprotocol/sdk'; import { Handler } from '@netlify/functions'; import { chainIdtoChain, chainIdToConfig } from '@ionicprotocol/chains'; import axios from 'axios'; @@ -50,9 +50,20 @@ export const updateAssetTvl = async (chainId: SupportedChains) => { try { const cTokenContract = sdk.createICErc20(asset.cToken); const tvlUnderlyingBig = await cTokenContract.read.getTotalUnderlyingSupplied(); - const tvlUnderlying = formatUnits(tvlUnderlyingBig, 18); + const formattedTokenAddress = `0x${asset.underlyingToken.replace(/^0x/, "")}` as `0x${string}`; + + // Fetch the token decimals + const tokenDecimals = await publicClient.readContract({ + address: formattedTokenAddress, + abi: erc20Abi, + functionName: "decimals", + }); + + // Adjust the formatting based on token decimals + const tvlUnderlying = formatUnits(tvlUnderlyingBig, tokenDecimals); const underlyingPrice = Number(formatEther(asset.underlyingPrice)); const tvlNative = (parseFloat(tvlUnderlying) * underlyingPrice).toFixed(2); + results.push({ cTokenAddress: asset.cToken, diff --git a/packages/functions/src/controllers/total-tvl.ts b/packages/functions/src/controllers/total-tvl.ts index 0ed8d6831b..6beee4fc9d 100644 --- a/packages/functions/src/controllers/total-tvl.ts +++ b/packages/functions/src/controllers/total-tvl.ts @@ -1,30 +1,55 @@ import { SupportedChains } from '@ionicprotocol/types'; import { functionsAlert } from '../alert'; import { environment, supabase } from '../config'; -import { updateAssetTvl } from './asset-tvl'; +import { updateAssetTvl } from './asset-tvl'; +import axios from 'axios'; // Assuming axios is already installed for API requests import { Handler } from '@netlify/functions'; +// Function to get ETH to USD conversion rate from Coingecko API +const getEthToUsdRate = async (): Promise => { + try { + const response = await axios.get( + 'https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd' + ); + return response.data.ethereum.usd; + } catch (error) { + console.error('Error fetching ETH to USD rate:', error); + throw new Error('Unable to fetch ETH to USD conversion rate'); + } +}; + // Function to calculate and store total TVL per chain -export const updateTotalTvl = async (chainId: SupportedChains) => { +export const updateTotalTvl = async (chainId: SupportedChains): Promise => { try { // Call updateAssetTvl to get the TVL for each asset const results = await updateAssetTvl(chainId); - // Summing up the total TVL (native) - const totalTvlNative = results.reduce((total: number, asset: { tvlNative: string; }) => { + // Log each asset's TVL + results.forEach((asset: { tvlNative: string }) => { + console.log(`Asset TVL (native): ${asset.tvlNative}`); + }); + + // Summing up the total TVL (native) in ETH + const totalTvlNative = results.reduce((total: number, asset: { tvlNative: string }) => { return total + parseFloat(asset.tvlNative); }, 0); - //underlying - // const totaltvlUnderlying = results.reduce((total: number, asset: { tvlUnderlying: string; }) => { - // return total + parseFloat(asset.tvlUnderlying); - // }, 0); - + + // Log the total TVL in native ETH + console.log(`Total TVL (native ETH): ${totalTvlNative}`); + + // Fetch ETH to USD conversion rate + const ethToUsdRate = await getEthToUsdRate(); + console.log(`ETH to USD rate: ${ethToUsdRate}`); + + // Convert total TVL from ETH to USD + const totalTvlUsd = totalTvlNative * ethToUsdRate; + console.log(`Total TVL (USD): ${totalTvlUsd}`); + // Create row for the total TVL data const totalTvlRow = { chain_id: chainId, - total_tvl_native: totalTvlNative.toFixed(2), // Storing as string for fixed precision - // total_tvl_Underlying: totaltvlUnderlying.toFixed(2), - // created_at: new Date().getTime(), + total_tvl_native: totalTvlNative.toFixed(18), // Storing as string for fixed precision + total_tvl_usd: totalTvlUsd.toFixed(2), // Store the USD equivalent }; // Insert the total TVL row into the database @@ -41,6 +66,7 @@ export const updateTotalTvl = async (chainId: SupportedChains) => { } }; + // Create a Netlify function handler for calculating the total TVL export const createTotalTvlHandler = (chain: SupportedChains): Handler => @@ -52,8 +78,8 @@ export const createTotalTvlHandler = statusCode: 200, body: JSON.stringify({ message: 'Total TVL calculation done' }), }; - } catch (err : any) { - console.error('Error in createTotalTvlHandler:', err ); + } catch (err: any) { + console.error('Error in createTotalTvlHandler:', err); return { statusCode: 500, body: JSON.stringify({ message: err.message }),