22pragma solidity 0.8.10 ;
33
44import {VersionedInitializable} from '@aave/core-v3/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol ' ;
5+ import {SafeCast} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/SafeCast.sol ' ;
56import {IScaledBalanceToken} from '@aave/core-v3/contracts/interfaces/IScaledBalanceToken.sol ' ;
67import {RewardsDistributor} from './RewardsDistributor.sol ' ;
78import {IRewardsController} from './interfaces/IRewardsController.sol ' ;
89import {ITransferStrategyBase} from './interfaces/ITransferStrategyBase.sol ' ;
9- import {RewardsDistributorTypes } from './libraries/RewardsDistributorTypes .sol ' ;
10+ import {RewardsDataTypes } from './libraries/RewardsDataTypes .sol ' ;
1011import {IEACAggregatorProxy} from '../misc/interfaces/IEACAggregatorProxy.sol ' ;
1112
1213/**
@@ -15,6 +16,8 @@ import {IEACAggregatorProxy} from '../misc/interfaces/IEACAggregatorProxy.sol';
1516 * @author Aave
1617 **/
1718contract RewardsController is RewardsDistributor , VersionedInitializable , IRewardsController {
19+ using SafeCast for uint256 ;
20+
1821 uint256 public constant REVISION = 1 ;
1922
2023 // This mapping allows whitelisted addresses to claim on behalf of others
@@ -69,7 +72,7 @@ contract RewardsController is RewardsDistributor, VersionedInitializable, IRewar
6972 }
7073
7174 /// @inheritdoc IRewardsController
72- function configureAssets (RewardsDistributorTypes .RewardsConfigInput[] memory config )
75+ function configureAssets (RewardsDataTypes .RewardsConfigInput[] memory config )
7376 external
7477 override
7578 onlyEmissionManager
@@ -109,7 +112,7 @@ contract RewardsController is RewardsDistributor, VersionedInitializable, IRewar
109112 uint256 totalSupply ,
110113 uint256 userBalance
111114 ) external override {
112- _updateUserRewardsPerAssetInternal (msg .sender , user, userBalance, totalSupply);
115+ _updateData (msg .sender , user, userBalance, totalSupply);
113116 }
114117
115118 /// @inheritdoc IRewardsController
@@ -187,28 +190,28 @@ contract RewardsController is RewardsDistributor, VersionedInitializable, IRewar
187190 }
188191
189192 /**
190- * @dev Get usage statistics of a list of assets that supports IScaledBalanceToken interface
193+ * @dev Get user balances and total supply of all the assets specified by the assets parameter
191194 * @param assets List of assets to retrieve user balance and total supply
192195 * @param user Address of the user
193- * @return userState contains a list of usage statistics like user balance and total supply of the assets passed as argument
196+ * @return userAssetBalances contains a list of structs with user balance and total supply of the given assets
194197 */
195- function _getUserStake (address [] calldata assets , address user )
198+ function _getUserAssetBalances (address [] calldata assets , address user )
196199 internal
197200 view
198201 override
199- returns (RewardsDistributorTypes.UserAssetStatsInput [] memory userState )
202+ returns (RewardsDataTypes.UserAssetBalance [] memory userAssetBalances )
200203 {
201- userState = new RewardsDistributorTypes. UserAssetStatsInput [](assets.length );
204+ userAssetBalances = new RewardsDataTypes. UserAssetBalance [](assets.length );
202205 for (uint256 i = 0 ; i < assets.length ; i++ ) {
203- userState [i].underlyingAsset = assets[i];
204- (userState [i].userBalance, userState [i].totalSupply) = IScaledBalanceToken (assets[i])
206+ userAssetBalances [i].asset = assets[i];
207+ (userAssetBalances [i].userBalance, userAssetBalances [i].totalSupply) = IScaledBalanceToken (assets[i])
205208 .getScaledUserBalanceAndSupply (user);
206209 }
207- return userState ;
210+ return userAssetBalances ;
208211 }
209212
210213 /**
211- * @dev Claims one type of reward for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards.
214+ * @dev Claims one type of reward for a user on behalf, on all the assets of the pool, accumulating the pending rewards.
212215 * @param assets List of assets to check eligible distributions before claiming rewards
213216 * @param amount Amount of rewards to claim
214217 * @param claimer Address of the claimer who claims rewards on behalf of user
@@ -228,28 +231,35 @@ contract RewardsController is RewardsDistributor, VersionedInitializable, IRewar
228231 if (amount == 0 ) {
229232 return 0 ;
230233 }
231- uint256 unclaimedRewards = _usersUnclaimedRewards[user][reward] ;
234+ uint256 totalRewards ;
232235
233- if (amount > unclaimedRewards) {
234- _distributeRewards (user, _getUserStake (assets, user));
235- unclaimedRewards = _usersUnclaimedRewards[user][reward];
236+ _updateDataMultiple (user, _getUserAssetBalances (assets, user));
237+ for (uint256 i = 0 ; i < assets.length ; i++ ) {
238+ address asset = assets[i];
239+ totalRewards += _assets[asset].rewards[reward].usersData[user].accrued;
240+
241+ if (totalRewards <= amount) {
242+ _assets[asset].rewards[reward].usersData[user].accrued = 0 ;
243+ } else {
244+ uint256 difference = totalRewards - amount;
245+ totalRewards -= difference;
246+ _assets[asset].rewards[reward].usersData[user].accrued = difference.toUint128 ();
247+ break ;
248+ }
236249 }
237250
238- if (unclaimedRewards == 0 ) {
251+ if (totalRewards == 0 ) {
239252 return 0 ;
240253 }
241254
242- uint256 amountToClaim = amount > unclaimedRewards ? unclaimedRewards : amount;
243- _usersUnclaimedRewards[user][reward] = unclaimedRewards - amountToClaim; // Safe due to the previous line
244-
245- _transferRewards (to, reward, amountToClaim);
246- emit RewardsClaimed (user, reward, to, claimer, amountToClaim);
255+ _transferRewards (to, reward, totalRewards);
256+ emit RewardsClaimed (user, reward, to, claimer, totalRewards);
247257
248- return amountToClaim ;
258+ return totalRewards ;
249259 }
250260
251261 /**
252- * @dev Claims one type of reward for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards.
262+ * @dev Claims one type of reward for a user on behalf, on all the assets of the pool, accumulating the pending rewards.
253263 * @param assets List of assets to check eligible distributions before claiming rewards
254264 * @param claimer Address of the claimer on behalf of user
255265 * @param user Address to check and claim rewards
@@ -264,24 +274,29 @@ contract RewardsController is RewardsDistributor, VersionedInitializable, IRewar
264274 address user ,
265275 address to
266276 ) internal returns (address [] memory rewardsList , uint256 [] memory claimedAmounts ) {
267- _distributeRewards (user, _getUserStake (assets, user));
277+ uint256 rewardsListLength = _rewardsList.length ;
278+ rewardsList = new address [](rewardsListLength);
279+ claimedAmounts = new uint256 [](rewardsListLength);
268280
269- rewardsList = new address [](_rewardsList.length );
270- claimedAmounts = new uint256 [](_rewardsList.length );
281+ _updateDataMultiple (user, _getUserAssetBalances (assets, user));
271282
272- for (uint256 i = 0 ; i < _rewardsList .length ; i++ ) {
273- address reward = _rewardsList [i];
274- uint256 rewardAmount = _usersUnclaimedRewards[user][reward];
275-
276- rewardsList[i ] = reward ;
277- claimedAmounts[i] = rewardAmount;
278-
279- if (rewardAmount != 0 ) {
280- _usersUnclaimedRewards[user][reward] = 0 ;
281- _transferRewards (to, reward, rewardAmount) ;
282- emit RewardsClaimed (user, reward, to, claimer, rewardAmount);
283+ for (uint256 i = 0 ; i < assets .length ; i++ ) {
284+ address asset = assets [i];
285+ for ( uint256 j = 0 ; j < rewardsListLength; j ++ ) {
286+ if (rewardsList[j] == address ( 0 )) {
287+ rewardsList[j ] = _rewardsList[j] ;
288+ }
289+ uint256 rewardAmount = _assets[asset].rewards[rewardsList[j]].usersData[user].accrued;
290+ if (rewardAmount != 0 ) {
291+ claimedAmounts[j] += rewardAmount ;
292+ _assets[asset].rewards[rewardsList[j]].usersData[user].accrued = 0 ;
293+ }
283294 }
284295 }
296+ for (uint256 i = 0 ; i < rewardsListLength; i++ ) {
297+ _transferRewards (to, rewardsList[i], claimedAmounts[i]);
298+ emit RewardsClaimed (user, rewardsList[i], to, claimer, claimedAmounts[i]);
299+ }
285300 return (rewardsList, claimedAmounts);
286301 }
287302
@@ -338,7 +353,7 @@ contract RewardsController is RewardsDistributor, VersionedInitializable, IRewar
338353 }
339354
340355 /**
341- * @dev internal function to update the Price Oracle of a reward token. The Price Oracle must follow Chainlink IEACAggregatorProxy interface.
356+ * @dev Update the Price Oracle of a reward token. The Price Oracle must follow Chainlink IEACAggregatorProxy interface.
342357 * @notice The Price Oracle of a reward is used for displaying correct data about the incentives at the UI frontend.
343358 * @param reward The address of the reward token
344359 * @param rewardOracle The address of the price oracle
0 commit comments