initial version

This commit is contained in:
andyk 2020-10-14 16:54:22 +03:00
parent 543c3f5c9c
commit e35882b6cb
2 changed files with 238 additions and 0 deletions

View File

@ -0,0 +1,82 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
interface IUiPoolDataProvider {
struct AggregatedReserveData {
address underlyingAsset;
string name;
string symbol;
uint256 decimals;
uint256 ltv;
uint256 liquidationThreshold;
uint256 liquidationBonus;
uint256 reserveFactor;
bool usageAsCollateralEnabled;
bool borrowingEnabled;
bool stableBorrowRateEnabled;
bool isActive;
bool isFreezed;
ReserveLogic.ReserveData baseData;
uint256 availableLiquidity;
uint256 totalBorrowsStable;
uint256 totalBorrowsVariable;
uint256 utilizationRate;
uint256 priceInEth;
uint256 variableRateSlope1;
uint256 variableRateSlope2;
uint256 stableRateSlope1;
uint256 stableRateSlope2;
}
//
// struct ReserveData {
// uint256 averageStableBorrowRate;
// uint256 totalLiquidity;
// }
struct UserReserveData {
address underlyingAsset;
uint256 principalATokenBalance;
bool usageAsCollateralEnabledOnUser;
uint256 stableBorrowRate;
uint256 principalVariableBorrows;
uint256 principalStableBorrows;
uint256 stableBorrowLastUpdateTimestamp;
}
//
// struct ATokenSupplyData {
// string name;
// string symbol;
// uint8 decimals;
// uint256 totalSupply;
// address aTokenAddress;
// }
function getReservesData(ILendingPoolAddressesProvider provider, address user)
external
view
returns (
AggregatedReserveData[] memory,
UserReserveData[] memory,
uint256
);
// function getUserReservesData(ILendingPoolAddressesProvider provider, address user)
// external
// view
// returns (UserReserveData[] memory);
//
// function getAllATokenSupply(ILendingPoolAddressesProvider provider)
// external
// view
// returns (ATokenSupplyData[] memory);
//
// function getATokenSupply(address[] calldata aTokens)
// external
// view
// returns (ATokenSupplyData[] memory);
}

View File

@ -0,0 +1,156 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
import {IUiPoolDataProvider} from './IUiPoolDataProvider.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol';
import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol';
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';
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
import '../lendingpool/DefaultReserveInterestRateStrategy.sol';
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
reserveData.baseData = lendingPool.getReserveData(reserveData.underlyingAsset);
reserveData.priceInEth = oracle.getAssetPrice(reserveData.underlyingAsset);
reserveData.availableLiquidity = IERC20Detailed(reserveData.underlyingAsset).balanceOf(
reserveData.baseData.aTokenAddress
);
reserveData.totalBorrowsStable = IERC20Detailed(reserveData.baseData.stableDebtTokenAddress)
.totalSupply();
reserveData.totalBorrowsVariable = IERC20Detailed(
reserveData
.baseData
.variableDebtTokenAddress
)
.totalSupply();
uint256 totalBorrows = reserveData.totalBorrowsStable + reserveData.totalBorrowsVariable;
reserveData.utilizationRate = totalBorrows == 0
? 0
: totalBorrows.rayDiv(totalBorrows + reserveData.availableLiquidity);
// reserve configuration
// we're getting this info from the aToken, because some of assets can be not compliant with ETC20Detailed
reserveData.symbol = IERC20Detailed(reserveData.baseData.aTokenAddress).symbol();
reserveData.name = '';
(
reserveData.ltv,
reserveData.liquidationThreshold,
reserveData.liquidationBonus,
reserveData.decimals,
reserveData.reserveFactor
) = reserveData.baseData.configuration.getParamsMemory();
(
reserveData.isActive,
reserveData.isFreezed,
reserveData.borrowingEnabled,
reserveData.stableBorrowRateEnabled
) = reserveData.baseData.configuration.getFlagsMemory();
reserveData.usageAsCollateralEnabled = reserveData.ltv != 0;
(
reserveData.variableRateSlope1,
reserveData.variableRateSlope2,
reserveData.stableRateSlope1,
reserveData.stableRateSlope2
) = getInterestRateStrategySlopes(
DefaultReserveInterestRateStrategy(reserveData.baseData.interestRateStrategyAddress)
);
if (user != address(0)) {
// user reserve data
userReservesData[i].underlyingAsset = reserveData.underlyingAsset;
userReservesData[i].principalATokenBalance = IAToken(reserveData.baseData.aTokenAddress)
.scaledBalanceOf(user);
userReservesData[i].usageAsCollateralEnabledOnUser = userConfig.isUsingAsCollateral(i);
if (userConfig.isBorrowing(i)) {
userReservesData[i].principalVariableBorrows = IVariableDebtToken(
reserveData
.baseData
.variableDebtTokenAddress
)
.scaledBalanceOf(user);
userReservesData[i].principalStableBorrows = IStableDebtToken(
reserveData
.baseData
.stableDebtTokenAddress
)
.principalBalanceOf(user);
if (userReservesData[i].principalStableBorrows != 0) {
userReservesData[i].stableBorrowRate = IStableDebtToken(
reserveData
.baseData
.stableDebtTokenAddress
)
.getUserStableRate(user);
userReservesData[i].stableBorrowLastUpdateTimestamp = IStableDebtToken(
reserveData
.baseData
.stableDebtTokenAddress
)
.getUserLastUpdated(user);
}
}
}
}
return (reservesData, userReservesData, oracle.getAssetPrice(MOCK_USD_ADDRESS));
}
}