feat: RewardsAwareAToken replace transfer to safeTransfer at rewards, add early return at updateDistribution if address is 0x0, remove unneeded updateDistribution calls at mint and burn.

This commit is contained in:
David Racero 2021-06-03 14:56:42 +02:00
parent ee142e565f
commit 0d3b155eeb
2 changed files with 23 additions and 8 deletions

View File

@ -10,7 +10,6 @@ import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
import {IRewardsAwareAToken} from '../../interfaces/IRewardsAwareAToken.sol'; import {IRewardsAwareAToken} from '../../interfaces/IRewardsAwareAToken.sol';
import {IAToken} from '../../interfaces/IRewardsAwareAToken.sol'; import {IAToken} from '../../interfaces/IRewardsAwareAToken.sol';
import {WadRayMath} from '../../protocol/libraries/math/WadRayMath.sol';
import {PercentageMath} from '../../protocol/libraries/math/PercentageMath.sol'; import {PercentageMath} from '../../protocol/libraries/math/PercentageMath.sol';
/** /**
@ -20,7 +19,6 @@ import {PercentageMath} from '../../protocol/libraries/math/PercentageMath.sol';
*/ */
abstract contract RewardsAwareAToken is AToken, IRewardsAwareAToken { abstract contract RewardsAwareAToken is AToken, IRewardsAwareAToken {
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
using WadRayMath for uint256;
using PercentageMath for uint256; using PercentageMath for uint256;
// Precision of the multiplier for calculating distribution percentages // Precision of the multiplier for calculating distribution percentages
@ -172,7 +170,7 @@ abstract contract RewardsAwareAToken is AToken, IRewardsAwareAToken {
_unstake(UNDERLYING_ASSET_ADDRESS(), amount); _unstake(UNDERLYING_ASSET_ADDRESS(), amount);
// Update distribution of rewards // Update distribution of rewards
_updateDistribution(user); // _updateDistribution(user);
// burns aTokens // burns aTokens
return super.burn(user, receiverOfUnderlying, amount, index); return super.burn(user, receiverOfUnderlying, amount, index);
@ -195,7 +193,7 @@ abstract contract RewardsAwareAToken is AToken, IRewardsAwareAToken {
_stake(UNDERLYING_ASSET_ADDRESS(), amount); _stake(UNDERLYING_ASSET_ADDRESS(), amount);
// Update distribution of rewards // Update distribution of rewards
_updateDistribution(user); // _updateDistribution(user);
// mint aTokens // mint aTokens
return super.mint(user, amount, index); return super.mint(user, amount, index);
@ -384,6 +382,8 @@ abstract contract RewardsAwareAToken is AToken, IRewardsAwareAToken {
* @param user The `user` address to update the rewards index and retrieve latest reward distribution * @param user The `user` address to update the rewards index and retrieve latest reward distribution
*/ */
function _updateDistribution(address user) internal { function _updateDistribution(address user) internal {
if (user == address(0)) return;
uint256 aTokenBalance = balanceOf(user); uint256 aTokenBalance = balanceOf(user);
if (aTokenBalance == 0) { if (aTokenBalance == 0) {
return; return;
@ -444,12 +444,12 @@ abstract contract RewardsAwareAToken is AToken, IRewardsAwareAToken {
uint256 reserveRewards = unstaked.percentMul(rewardsReserveFactor); uint256 reserveRewards = unstaked.percentMul(rewardsReserveFactor);
if (reserveRewards > 0) { if (reserveRewards > 0) {
userRewards = unstaked.sub(reserveRewards); userRewards = unstaked.sub(reserveRewards);
IERC20(token).transfer(_treasury, reserveRewards); IERC20(token).safeTransfer(_treasury, reserveRewards);
} }
} }
// Transfer rewards to user // Transfer rewards to user
IERC20(token).transfer(msg.sender, userRewards); IERC20(token).safeTransfer(msg.sender, userRewards);
emit Claim(msg.sender, token, accruedRewards, userRewards); emit Claim(msg.sender, token, accruedRewards, userRewards);
} }
} }

View File

@ -259,8 +259,13 @@ makeSuite('Reward Aware AToken', (testEnv: TestEnv) => {
`\taRew Total supply: ${formatEther( `\taRew Total supply: ${formatEther(
await aRew.totalSupply() await aRew.totalSupply()
)}. Rewards in contract: ${formatEther( )}. Rewards in contract: ${formatEther(
await rew.balanceOf(aRew.address) await (await rew.balanceOf(aRew.address)).sub(await aRew.totalSupply())
)}. Summed claimable: ${formatEther(summedClaimable)}` )}. Summed claimable: ${formatEther(summedClaimable)}
. Summed aRew REW balance + claimable REW: ${formatEther(
await (await rew.balanceOf(aRew.address))
.sub(await aRew.totalSupply())
.add(await rew.getClaimableRewards(aRew.address))
)}`
); );
}; };
@ -289,15 +294,25 @@ makeSuite('Reward Aware AToken', (testEnv: TestEnv) => {
console.log(`Withdraws`); console.log(`Withdraws`);
for (let i = 0; i < users.length; i++) { for (let i = 0; i < users.length; i++) {
console.log('--p');
await printState();
console.log('--p');
await pool await pool
.connect(users[i].signer) .connect(users[i].signer)
.withdraw(rew.address, MAX_UINT_AMOUNT, users[i].address); .withdraw(rew.address, MAX_UINT_AMOUNT, users[i].address);
console.log('--a');
await printState();
console.log('--a');
} }
// Claims and check rewards // Claims and check rewards
console.log(`Claim`); console.log(`Claim`);
for (let i = 0; i < users.length; i++) { for (let i = 0; i < users.length; i++) {
console.log('--c');
await printState();
console.log('--c');
await claim(users[i]); await claim(users[i]);
console.log('claimed', users[i].address);
} }
await printState(); await printState();