2020-06-12 20:12:53 +00:00
|
|
|
import {LendingPool} from "../../../types/LendingPool";
|
|
|
|
import {ReserveData, UserReserveData} from "./interfaces";
|
|
|
|
import {
|
|
|
|
getLendingRateOracle,
|
|
|
|
getIErc20Detailed,
|
|
|
|
getMintableErc20,
|
|
|
|
getAToken,
|
|
|
|
} from "../../../helpers/contracts-helpers";
|
|
|
|
import {MOCK_ETH_ADDRESS, ZERO_ADDRESS} from "../../../helpers/constants";
|
|
|
|
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<ReserveData> => {
|
|
|
|
const data: any = await pool.getReserveData(reserve);
|
2020-06-26 14:58:52 +00:00
|
|
|
const configuration: any = await pool.getReserveConfigurationData(reserve);
|
2020-06-12 20:12:53 +00:00
|
|
|
const rateOracle = await getLendingRateOracle();
|
|
|
|
|
|
|
|
const rate = (await rateOracle.getMarketBorrowRate(reserve)).toString();
|
|
|
|
|
|
|
|
const isEthReserve = reserve === MOCK_ETH_ADDRESS;
|
|
|
|
let symbol = "ETH";
|
|
|
|
let decimals = new BigNumber(18);
|
|
|
|
if (!isEthReserve) {
|
|
|
|
const token = await getIErc20Detailed(reserve);
|
|
|
|
symbol = await token.symbol();
|
|
|
|
decimals = new BigNumber(await token.decimals());
|
|
|
|
}
|
2020-06-26 14:58:52 +00:00
|
|
|
|
|
|
|
const totalLiquidity = new BigNumber(data.availableLiquidity).plus(data.totalBorrowsStable).plus(data.totalBorrowsVariable);
|
|
|
|
|
|
|
|
const utilizationRate = new BigNumber(totalLiquidity.eq(0) ? 0 : new BigNumber(data.totalBorrowsStable).plus(data.totalBorrowsVariable).rayDiv(totalLiquidity))
|
|
|
|
|
2020-06-12 20:12:53 +00:00
|
|
|
return {
|
2020-06-26 14:58:52 +00:00
|
|
|
totalLiquidity,
|
|
|
|
utilizationRate,
|
2020-06-12 20:12:53 +00:00
|
|
|
availableLiquidity: new BigNumber(data.availableLiquidity),
|
|
|
|
totalBorrowsStable: new BigNumber(data.totalBorrowsStable),
|
|
|
|
totalBorrowsVariable: new BigNumber(data.totalBorrowsVariable),
|
|
|
|
liquidityRate: new BigNumber(data.liquidityRate),
|
|
|
|
variableBorrowRate: new BigNumber(data.variableBorrowRate),
|
|
|
|
stableBorrowRate: new BigNumber(data.stableBorrowRate),
|
|
|
|
averageStableBorrowRate: new BigNumber(data.averageStableBorrowRate),
|
|
|
|
liquidityIndex: new BigNumber(data.liquidityIndex),
|
|
|
|
variableBorrowIndex: new BigNumber(data.variableBorrowIndex),
|
|
|
|
lastUpdateTimestamp: new BigNumber(data.lastUpdateTimestamp),
|
|
|
|
address: reserve,
|
2020-06-26 14:58:52 +00:00
|
|
|
aTokenAddress: configuration.aTokenAddress,
|
2020-06-12 20:12:53 +00:00
|
|
|
symbol,
|
|
|
|
decimals,
|
|
|
|
marketStableRate: new BigNumber(rate),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
export const getUserData = async (
|
|
|
|
pool: LendingPool,
|
|
|
|
reserve: string,
|
|
|
|
user: string
|
|
|
|
): Promise<UserReserveData> => {
|
2020-06-30 12:09:28 +00:00
|
|
|
const [userData, aTokenData] = await Promise.all([
|
2020-06-12 20:12:53 +00:00
|
|
|
pool.getUserReserveData(reserve, user),
|
2020-06-20 23:40:03 +00:00
|
|
|
getATokenUserData(reserve, user, pool),
|
2020-06-12 20:12:53 +00:00
|
|
|
]);
|
|
|
|
|
|
|
|
const [
|
|
|
|
userIndex,
|
|
|
|
redirectedBalance,
|
|
|
|
principalATokenBalance,
|
|
|
|
redirectionAddressRedirectedBalance,
|
|
|
|
interestRedirectionAddress,
|
|
|
|
] = aTokenData;
|
|
|
|
|
|
|
|
let walletBalance;
|
|
|
|
|
|
|
|
if (reserve === MOCK_ETH_ADDRESS) {
|
|
|
|
walletBalance = new BigNumber(
|
|
|
|
(await BRE.ethers.provider.getBalance(user)).toString()
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
const token = await getMintableErc20(reserve);
|
|
|
|
walletBalance = new BigNumber((await token.balanceOf(user)).toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
principalATokenBalance: new BigNumber(principalATokenBalance),
|
|
|
|
interestRedirectionAddress,
|
|
|
|
redirectionAddressRedirectedBalance: new BigNumber(
|
|
|
|
redirectionAddressRedirectedBalance
|
|
|
|
),
|
|
|
|
redirectedBalance: new BigNumber(redirectedBalance),
|
|
|
|
currentATokenUserIndex: new BigNumber(userIndex),
|
2020-06-30 12:09:28 +00:00
|
|
|
currentATokenBalance: new BigNumber(userData.currentATokenBalance.toString()),
|
|
|
|
currentStableBorrowBalance: new BigNumber(userData.currentStableBorrowBalance.toString()),
|
|
|
|
currentVariableBorrowBalance: new BigNumber(userData.currentVariableBorrowBalance.toString()),
|
|
|
|
principalStableBorrowBalance: new BigNumber(userData.principalStableBorrowBalance.toString()),
|
|
|
|
principalVariableBorrowBalance: new BigNumber(userData.principalVariableBorrowBalance.toString()),
|
|
|
|
variableBorrowIndex: new BigNumber(userData.variableBorrowIndex.toString()),
|
|
|
|
stableBorrowRate: new BigNumber(userData.stableBorrowRate.toString()),
|
|
|
|
liquidityRate: new BigNumber(userData.liquidityRate.toString()),
|
2020-06-12 20:12:53 +00:00
|
|
|
usageAsCollateralEnabled: userData.usageAsCollateralEnabled,
|
2020-07-03 21:20:02 +00:00
|
|
|
stableRateLastUpdated: new BigNumber(userData.stableRateLastUpdated.toString()),
|
2020-06-12 20:12:53 +00:00
|
|
|
walletBalance,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
export const getReserveAddressFromSymbol = async (symbol: string) => {
|
|
|
|
if (symbol.toUpperCase() === "ETH") {
|
|
|
|
return MOCK_ETH_ADDRESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
2020-06-20 23:40:03 +00:00
|
|
|
pool: LendingPool
|
2020-06-12 20:12:53 +00:00
|
|
|
) => {
|
2020-06-20 23:40:03 +00:00
|
|
|
const aTokenAddress: string = (await pool.getReserveConfigurationData(reserve)).aTokenAddress;
|
2020-06-12 20:12:53 +00:00
|
|
|
|
|
|
|
const aToken = await getAToken(aTokenAddress);
|
|
|
|
const [
|
|
|
|
userIndex,
|
|
|
|
interestRedirectionAddress,
|
|
|
|
redirectedBalance,
|
|
|
|
principalTokenBalance,
|
|
|
|
] = await Promise.all([
|
|
|
|
aToken.getUserIndex(user),
|
|
|
|
aToken.getInterestRedirectionAddress(user),
|
|
|
|
aToken.getRedirectedBalance(user),
|
|
|
|
aToken.principalBalanceOf(user),
|
|
|
|
]);
|
|
|
|
|
|
|
|
const redirectionAddressRedirectedBalance =
|
|
|
|
interestRedirectionAddress !== ZERO_ADDRESS
|
|
|
|
? new BigNumber(
|
|
|
|
(
|
|
|
|
await aToken.getRedirectedBalance(interestRedirectionAddress)
|
|
|
|
).toString()
|
|
|
|
)
|
|
|
|
: new BigNumber("0");
|
|
|
|
|
|
|
|
return [
|
|
|
|
userIndex.toString(),
|
|
|
|
redirectedBalance.toString(),
|
|
|
|
principalTokenBalance.toString(),
|
|
|
|
redirectionAddressRedirectedBalance.toString(),
|
|
|
|
interestRedirectionAddress,
|
|
|
|
];
|
|
|
|
};
|