import {LendingPool} from '../../../types/LendingPool'; import {ReserveData, UserReserveData} from './interfaces'; import { getLendingRateOracle, getIErc20Detailed, getMintableErc20, getAToken, getStableDebtToken, getVariableDebtToken } from '../../../helpers/contracts-helpers'; import {tEthereumAddress} from '../../../helpers/types'; import BigNumber from 'bignumber.js'; import {getDb, BRE} from '../../../helpers/misc-utils'; export const getReserveData = async ( pool: LendingPool, reserve: tEthereumAddress ): Promise => { const [reserveData, tokenAddresses, rateOracle, token] = await Promise.all([ pool.getReserveData(reserve), pool.getReserveTokensAddresses(reserve), getLendingRateOracle(), getIErc20Detailed(reserve), ]); const stableDebtToken = await getStableDebtToken(tokenAddresses.stableDebtTokenAddress); const variableDebtToken = await getVariableDebtToken(tokenAddresses.variableDebtTokenAddress); const [principalStableDebt] = await stableDebtToken.getPrincipalSupplyAndAvgRate(); const scaledVariableDebt = await variableDebtToken.scaledTotalSupply(); const rate = (await rateOracle.getMarketBorrowRate(reserve)).toString(); const symbol = await token.symbol(); const decimals = new BigNumber(await token.decimals()); const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString()) .plus(reserveData.totalStableDebt.toString()) .plus(reserveData.totalVariableDebt.toString()); const utilizationRate = new BigNumber( totalLiquidity.eq(0) ? 0 : new BigNumber(reserveData.totalStableDebt.toString()) .plus(reserveData.totalVariableDebt.toString()) .rayDiv(totalLiquidity) ); return { totalLiquidity, utilizationRate, availableLiquidity: new BigNumber(reserveData.availableLiquidity.toString()), totalStableDebt: new BigNumber(reserveData.totalStableDebt.toString()), totalVariableDebt: new BigNumber(reserveData.totalVariableDebt.toString()), liquidityRate: new BigNumber(reserveData.liquidityRate.toString()), variableBorrowRate: new BigNumber(reserveData.variableBorrowRate.toString()), stableBorrowRate: new BigNumber(reserveData.stableBorrowRate.toString()), averageStableBorrowRate: new BigNumber(reserveData.averageStableBorrowRate.toString()), liquidityIndex: new BigNumber(reserveData.liquidityIndex.toString()), variableBorrowIndex: new BigNumber(reserveData.variableBorrowIndex.toString()), lastUpdateTimestamp: new BigNumber(reserveData.lastUpdateTimestamp), principalStableDebt: new BigNumber(principalStableDebt.toString()), scaledVariableDebt: new BigNumber(scaledVariableDebt.toString()), address: reserve, aTokenAddress: tokenAddresses.aTokenAddress, symbol, decimals, marketStableRate: new BigNumber(rate), }; }; export const getUserData = async ( pool: LendingPool, reserve: string, user: tEthereumAddress, sender?: tEthereumAddress ): Promise => { const [userData, scaledATokenBalance] = await Promise.all([ pool.getUserReserveData(reserve, user), getATokenUserData(reserve, user, pool), ]); const token = await getMintableErc20(reserve); const walletBalance = new BigNumber((await token.balanceOf(sender || user)).toString()); return { scaledATokenBalance: new BigNumber(scaledATokenBalance), currentATokenBalance: new BigNumber(userData.currentATokenBalance.toString()), currentStableDebt: new BigNumber(userData.currentStableDebt.toString()), currentVariableDebt: new BigNumber(userData.currentVariableDebt.toString()), principalStableDebt: new BigNumber(userData.principalStableDebt.toString()), scaledVariableDebt: new BigNumber(userData.scaledVariableDebt.toString()), stableBorrowRate: new BigNumber(userData.stableBorrowRate.toString()), liquidityRate: new BigNumber(userData.liquidityRate.toString()), usageAsCollateralEnabled: userData.usageAsCollateralEnabled, stableRateLastUpdated: new BigNumber(userData.stableRateLastUpdated.toString()), walletBalance, }; }; export const getReserveAddressFromSymbol = async (symbol: string) => { const token = await getMintableErc20( (await getDb().get(`${symbol}.${BRE.network.name}`).value()).address ); if (!token) { throw `Could not find instance for contract ${symbol}`; } return token.address; }; const getATokenUserData = async (reserve: string, user: string, pool: LendingPool) => { const aTokenAddress: string = (await pool.getReserveTokensAddresses(reserve)).aTokenAddress; const aToken = await getAToken(aTokenAddress); const scaledBalance = await aToken.scaledBalanceOf(user); return scaledBalance.toString(); };