diff --git a/contracts/interfaces/IAaveIncentivesController.sol b/contracts/interfaces/IAaveIncentivesController.sol index c049bd77..5125ac7b 100644 --- a/contracts/interfaces/IAaveIncentivesController.sol +++ b/contracts/interfaces/IAaveIncentivesController.sol @@ -3,9 +3,24 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; interface IAaveIncentivesController { + struct AssetData { + uint128 emissionPerSecond; + uint128 lastUpdateTimestamp; + uint256 index; + } + + function REWARD_TOKEN() external view returns (address rewardToken); + + function assets(address underlying) external view returns (AssetData memory assets); + function handleAction( address user, uint256 userBalance, uint256 totalSupply ) external; + + function getRewardsBalance(address[] calldata assets, address user) + external + view + returns (uint256); } diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 65fdc4dd..4d61ee8d 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -4,6 +4,7 @@ pragma experimental ABIEncoderV2; import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol'; +import {IAaveIncentivesController} from '../interfaces/IAaveIncentivesController.sol'; import {IUiPoolDataProvider} from './interfaces/IUiPoolDataProvider.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; @@ -43,7 +44,11 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ); } - function getReservesData(ILendingPoolAddressesProvider provider, address user) + function getReservesData( + ILendingPoolAddressesProvider provider, + IAaveIncentivesController incentivesControllerAddr, + address user + ) external view override @@ -53,6 +58,8 @@ contract UiPoolDataProvider is IUiPoolDataProvider { uint256 ) { + IAaveIncentivesController incentivesController = + IAaveIncentivesController(incentivesControllerAddr); ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle()); address[] memory reserves = lendingPool.getReservesList(); @@ -122,6 +129,11 @@ contract UiPoolDataProvider is IUiPoolDataProvider { DefaultReserveInterestRateStrategy(reserveData.interestRateStrategyAddress) ); + // incentives + reserveData.emissionPerSecond = incentivesController + .assets(reserveData.underlyingAsset) + .emissionPerSecond; + if (user != address(0)) { // user reserve data userReservesData[i].underlyingAsset = reserveData.underlyingAsset; @@ -155,6 +167,43 @@ contract UiPoolDataProvider is IUiPoolDataProvider { } } } + return (reservesData, userReservesData, oracle.getAssetPrice(MOCK_USD_ADDRESS)); } + + function getUserIncentivesBalance( + ILendingPoolAddressesProvider provider, + IAaveIncentivesController incentivesControllerAddr, + address user + ) external view override returns (IncentivesDataUser memory) { + IAaveIncentivesController incentivesController = + IAaveIncentivesController(incentivesControllerAddr); + ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); + IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle()); + address[] memory reserves = lendingPool.getReservesList(); + + // array of atokens that have incentives + address[] memory incentivesATokens = new address[](user != address(0) ? reserves.length : 0); + + for (uint256 i = 0; i < reserves.length; i++) { + DataTypes.ReserveData memory baseData = lendingPool.getReserveData(reserves[i]); + if (user != address(0)) { + incentivesATokens[i] = baseData.aTokenAddress; + } + } + + IncentivesDataUser memory userRewardsBalance; + if (user != address(0)) { + userRewardsBalance.rewardToken = incentivesController.REWARD_TOKEN(); + userRewardsBalance.claimableRewards = incentivesController.getRewardsBalance( + incentivesATokens, + user + ); + userRewardsBalance.rewardTokenDecimals = IERC20Detailed(userRewardsBalance.rewardToken) + .decimals(); + userRewardsBalance.rewardTokenPriceEth = oracle.getAssetPrice(userRewardsBalance.rewardToken); + } + + return (userRewardsBalance); + } } diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol index 81a553e8..a1fb7572 100644 --- a/contracts/misc/interfaces/IUiPoolDataProvider.sol +++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol @@ -3,6 +3,7 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; +import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol'; interface IUiPoolDataProvider { struct AggregatedReserveData { @@ -41,7 +42,18 @@ interface IUiPoolDataProvider { uint256 variableRateSlope2; uint256 stableRateSlope1; uint256 stableRateSlope2; + // incentives + uint128 emissionPerSecond; } + + struct IncentivesDataUser { + address rewardToken; + uint256 claimableRewards; + uint256 rewardTokenDecimals; + uint256 rewardTokenPriceEth; + uint128 emissionPerSecond; + } + // // struct ReserveData { // uint256 averageStableBorrowRate; @@ -67,7 +79,11 @@ interface IUiPoolDataProvider { // address aTokenAddress; // } - function getReservesData(ILendingPoolAddressesProvider provider, address user) + function getReservesData( + ILendingPoolAddressesProvider provider, + IAaveIncentivesController incentives, + address user + ) external view returns ( @@ -76,6 +92,12 @@ interface IUiPoolDataProvider { uint256 ); + function getUserIncentivesBalance( + ILendingPoolAddressesProvider provider, + IAaveIncentivesController incentives, + address user + ) external view returns (IncentivesDataUser memory); + // function getUserReservesData(ILendingPoolAddressesProvider provider, address user) // external // view