2020-10-14 13:54:22 +00:00
|
|
|
// SPDX-License-Identifier: agpl-3.0
|
|
|
|
pragma solidity ^0.6.8;
|
|
|
|
pragma experimental ABIEncoderV2;
|
|
|
|
|
|
|
|
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
2020-11-06 14:06:52 +00:00
|
|
|
import {IUiPoolDataProvider} from './interfaces/IUiPoolDataProvider.sol';
|
2020-10-14 13:54:22 +00:00
|
|
|
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
2020-11-02 11:41:53 +00:00
|
|
|
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
2020-10-14 13:54:22 +00:00
|
|
|
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
|
|
|
import {IAToken} from '../tokenization/interfaces/IAToken.sol';
|
|
|
|
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
|
|
|
|
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
|
|
|
|
|
|
|
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
2020-10-30 10:14:42 +00:00
|
|
|
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
2020-10-14 13:54:22 +00:00
|
|
|
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
|
|
|
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
2020-10-30 10:14:42 +00:00
|
|
|
import {
|
|
|
|
DefaultReserveInterestRateStrategy
|
|
|
|
} from '../lendingpool/DefaultReserveInterestRateStrategy.sol';
|
2020-10-14 13:54:22 +00:00
|
|
|
|
|
|
|
contract UiPoolDataProvider is IUiPoolDataProvider {
|
|
|
|
using WadRayMath for uint256;
|
|
|
|
using ReserveConfiguration for ReserveConfiguration.Map;
|
|
|
|
using UserConfiguration for UserConfiguration.Map;
|
|
|
|
|
|
|
|
address public constant MOCK_USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96;
|
|
|
|
|
|
|
|
function getInterestRateStrategySlopes(DefaultReserveInterestRateStrategy interestRateStrategy)
|
|
|
|
internal
|
|
|
|
view
|
|
|
|
returns (
|
|
|
|
uint256,
|
|
|
|
uint256,
|
|
|
|
uint256,
|
|
|
|
uint256
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return (
|
|
|
|
interestRateStrategy.variableRateSlope1(),
|
|
|
|
interestRateStrategy.variableRateSlope2(),
|
|
|
|
interestRateStrategy.stableRateSlope1(),
|
|
|
|
interestRateStrategy.stableRateSlope2()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getReservesData(ILendingPoolAddressesProvider provider, address user)
|
|
|
|
external
|
|
|
|
override
|
|
|
|
view
|
|
|
|
returns (
|
|
|
|
AggregatedReserveData[] memory,
|
|
|
|
UserReserveData[] memory,
|
|
|
|
uint256
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ILendingPool lendingPool = ILendingPool(provider.getLendingPool());
|
|
|
|
IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle());
|
|
|
|
address[] memory reserves = lendingPool.getReservesList();
|
|
|
|
UserConfiguration.Map memory userConfig = lendingPool.getUserConfiguration(user);
|
|
|
|
|
|
|
|
AggregatedReserveData[] memory reservesData = new AggregatedReserveData[](reserves.length);
|
|
|
|
UserReserveData[] memory userReservesData = new UserReserveData[](
|
|
|
|
user != address(0) ? reserves.length : 0
|
|
|
|
);
|
|
|
|
|
|
|
|
for (uint256 i = 0; i < reserves.length; i++) {
|
|
|
|
AggregatedReserveData memory reserveData = reservesData[i];
|
|
|
|
reserveData.underlyingAsset = reserves[i];
|
|
|
|
|
|
|
|
// reserve current state
|
2020-10-30 10:14:42 +00:00
|
|
|
ReserveLogic.ReserveData memory baseData = lendingPool.getReserveData(
|
|
|
|
reserveData.underlyingAsset
|
|
|
|
);
|
|
|
|
reserveData.liquidityIndex = baseData.liquidityIndex;
|
|
|
|
reserveData.variableBorrowIndex = baseData.variableBorrowIndex;
|
|
|
|
reserveData.liquidityRate = baseData.currentLiquidityRate;
|
|
|
|
reserveData.variableBorrowRate = baseData.currentVariableBorrowRate;
|
|
|
|
reserveData.stableBorrowRate = baseData.currentStableBorrowRate;
|
|
|
|
reserveData.lastUpdateTimestamp = baseData.lastUpdateTimestamp;
|
|
|
|
reserveData.aTokenAddress = baseData.aTokenAddress;
|
|
|
|
reserveData.stableDebtTokenAddress = baseData.stableDebtTokenAddress;
|
|
|
|
reserveData.variableDebtTokenAddress = baseData.variableDebtTokenAddress;
|
|
|
|
reserveData.interestRateStrategyAddress = baseData.interestRateStrategyAddress;
|
2020-10-14 13:54:22 +00:00
|
|
|
reserveData.priceInEth = oracle.getAssetPrice(reserveData.underlyingAsset);
|
|
|
|
|
|
|
|
reserveData.availableLiquidity = IERC20Detailed(reserveData.underlyingAsset).balanceOf(
|
2020-10-30 10:14:42 +00:00
|
|
|
reserveData.aTokenAddress
|
2020-10-14 13:54:22 +00:00
|
|
|
);
|
2020-11-02 11:41:53 +00:00
|
|
|
(
|
|
|
|
reserveData.totalPrincipalStableDebt,
|
|
|
|
,
|
|
|
|
reserveData.averageStableRate,
|
|
|
|
reserveData.stableDebtLastUpdateTimestamp
|
2020-11-02 12:00:24 +00:00
|
|
|
) = IStableDebtToken(reserveData.stableDebtTokenAddress).getSupplyData();
|
|
|
|
reserveData.totalScaledVariableDebt = IVariableDebtToken(reserveData.variableDebtTokenAddress)
|
2020-11-02 11:41:53 +00:00
|
|
|
.scaledTotalSupply();
|
2020-10-14 13:54:22 +00:00
|
|
|
|
|
|
|
// reserve configuration
|
|
|
|
|
|
|
|
// we're getting this info from the aToken, because some of assets can be not compliant with ETC20Detailed
|
2020-10-30 10:14:42 +00:00
|
|
|
reserveData.symbol = IERC20Detailed(reserveData.aTokenAddress).symbol();
|
2020-10-14 13:54:22 +00:00
|
|
|
reserveData.name = '';
|
|
|
|
|
|
|
|
(
|
2020-10-30 10:14:42 +00:00
|
|
|
reserveData.baseLTVasCollateral,
|
|
|
|
reserveData.reserveLiquidationThreshold,
|
|
|
|
reserveData.reserveLiquidationBonus,
|
2020-10-14 13:54:22 +00:00
|
|
|
reserveData.decimals,
|
|
|
|
reserveData.reserveFactor
|
2020-10-30 10:14:42 +00:00
|
|
|
) = baseData.configuration.getParamsMemory();
|
2020-10-14 13:54:22 +00:00
|
|
|
(
|
|
|
|
reserveData.isActive,
|
2020-11-02 10:54:21 +00:00
|
|
|
reserveData.isFrozen,
|
2020-10-14 13:54:22 +00:00
|
|
|
reserveData.borrowingEnabled,
|
|
|
|
reserveData.stableBorrowRateEnabled
|
2020-10-30 10:14:42 +00:00
|
|
|
) = baseData.configuration.getFlagsMemory();
|
|
|
|
reserveData.usageAsCollateralEnabled = reserveData.baseLTVasCollateral != 0;
|
2020-10-14 13:54:22 +00:00
|
|
|
(
|
|
|
|
reserveData.variableRateSlope1,
|
|
|
|
reserveData.variableRateSlope2,
|
|
|
|
reserveData.stableRateSlope1,
|
|
|
|
reserveData.stableRateSlope2
|
|
|
|
) = getInterestRateStrategySlopes(
|
2020-10-30 10:14:42 +00:00
|
|
|
DefaultReserveInterestRateStrategy(reserveData.interestRateStrategyAddress)
|
2020-10-14 13:54:22 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
if (user != address(0)) {
|
|
|
|
// user reserve data
|
|
|
|
userReservesData[i].underlyingAsset = reserveData.underlyingAsset;
|
2020-11-02 12:00:24 +00:00
|
|
|
userReservesData[i].scaledATokenBalance = IAToken(reserveData.aTokenAddress)
|
2020-10-14 13:54:22 +00:00
|
|
|
.scaledBalanceOf(user);
|
|
|
|
userReservesData[i].usageAsCollateralEnabledOnUser = userConfig.isUsingAsCollateral(i);
|
|
|
|
|
|
|
|
if (userConfig.isBorrowing(i)) {
|
2020-11-02 09:37:24 +00:00
|
|
|
userReservesData[i].scaledVariableDebt = IVariableDebtToken(
|
2020-10-14 13:54:22 +00:00
|
|
|
reserveData
|
|
|
|
.variableDebtTokenAddress
|
|
|
|
)
|
|
|
|
.scaledBalanceOf(user);
|
2020-11-02 09:37:24 +00:00
|
|
|
userReservesData[i].principalStableDebt = IStableDebtToken(
|
2020-10-14 13:54:22 +00:00
|
|
|
reserveData
|
|
|
|
.stableDebtTokenAddress
|
|
|
|
)
|
|
|
|
.principalBalanceOf(user);
|
2020-11-02 09:37:24 +00:00
|
|
|
if (userReservesData[i].principalStableDebt != 0) {
|
2020-10-14 13:54:22 +00:00
|
|
|
userReservesData[i].stableBorrowRate = IStableDebtToken(
|
|
|
|
reserveData
|
|
|
|
.stableDebtTokenAddress
|
|
|
|
)
|
|
|
|
.getUserStableRate(user);
|
|
|
|
userReservesData[i].stableBorrowLastUpdateTimestamp = IStableDebtToken(
|
|
|
|
reserveData
|
|
|
|
.stableDebtTokenAddress
|
|
|
|
)
|
|
|
|
.getUserLastUpdated(user);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (reservesData, userReservesData, oracle.getAssetPrice(MOCK_USD_ADDRESS));
|
|
|
|
}
|
|
|
|
}
|