Platform: Code4rena
Start Date: 23/06/2023
Pot Size: $60,500 USDC
Total HM: 31
Participants: 132
Period: 10 days
Judge: 0xean
Total Solo HM: 10
Id: 254
League: ETH
Rank: 66/132
Findings: 1
Award: $84.36
🌟 Selected for report: 0
🚀 Solo Findings: 0
84.3563 USDC - $84.36
The ProtocolRewardContract is doing a wrong calculation to pay the rewards in case that the balance of the EURS is not enought (in case that is no enought in EUSD to pay the reward, the contract pay whit other token), i explain this clearly in the proof of concept.
In some cases the user can no claim his rewards because the function revert
To see this problem see this part of the getReward function:
function getReward() external updateReward(msg.sender) { ... uint256 balance = EUSD.sharesOf(address(this)); uint256 eUSDShare = balance >= reward ? reward : reward - balance; EUSD.transferShares(msg.sender, eUSDShare); ...}
If the contract doesn´t has enought balance to pai the whole reward in EUSD, it is substracting the reward and balance, This is wrong and we can see this with this simple example, imagine that the balance is 1 and the reward is 3 the final value of the eUSDShare is gonna be 2 which is still less than the balance, so the transferShares function is gonna revert.
manual review
to avoid this devs can send the whole balance in case that is not enought to pay the reward and then pay with the next token. see the code below :
function getReward() external updateReward(msg.sender) { uint reward = rewards[msg.sender]; if (reward > 0) { rewards[msg.sender] = 0; IEUSD EUSD = IEUSD(configurator.getEUSDAddress()); uint256 balance = EUSD.sharesOf(address(this)); uint256 eUSDShare = balance >= reward ? reward : balance; EUSD.transferShares(msg.sender, eUSDShare); if(reward > eUSDShare) { ERC20 peUSD = ERC20(configurator.peUSD()); uint256 peUSDBalance = peUSD.balanceOf(address(this)); if(peUSDBalance >= reward - eUSDShare) { peUSD.transfer(msg.sender, reward - eUSDShare); emit ClaimReward(msg.sender, EUSD.getMintedEUSDByShares(eUSDShare), address(peUSD), reward - eUSDShare, block.timestamp); } else { if(peUSDBalance > 0) { peUSD.transfer(msg.sender, peUSDBalance); } ERC20 token = ERC20(configurator.stableToken()); uint256 tokenAmount = (reward - eUSDShare - peUSDBalance) * token.decimals() / 1e18; token.transfer(msg.sender, tokenAmount); emit ClaimReward(msg.sender, EUSD.getMintedEUSDByShares(eUSDShare), address(token), reward - eUSDShare, block.timestamp); } } else { emit ClaimReward(msg.sender, EUSD.getMintedEUSDByShares(eUSDShare), address(0), 0, block.timestamp); }
Other
#0 - c4-pre-sort
2023-07-10T13:44:58Z
JeffCX marked the issue as duplicate of #161
#1 - c4-judge
2023-07-28T15:44:20Z
0xean marked the issue as satisfactory