31466 - [SC - Critical] Wrong reward calculation leads to rewards being...
Submitted on May 20th 2024 at 00:08:35 UTC by @RandomSec for Boost | Alchemix
Report ID: #31466
Report type: Smart Contract
Report severity: Critical
Target: https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/RevenueHandler.sol
Impacts:
Permanent freezing of unclaimed yield
Description
Hello,
upon running the tests supplied by you and changing them a bit I came across an issue that I couldn't find in the audit but that leads to most likely a high impact. The main reward calculation of RevenueHandler
happens in checkPoint()
. If a revenue token has a poolAdapter
set other than address(0)
, it is considered an alchemic-token. Then those tokens are melted
, i.e., as far as I understand, exchanged and then the received value is added to epochRevenues[currentEpoch][tokenConfig.debtToken]
. However, if it's not an alchemic-token, there is a miscalculation in the assigned rewards. If it is not, following code is executed (the else-clause):
However, all it does is applying the current balance to epochRevenues[currentEpoch][token]
. The problem is, that this will constantly increase epochRevenues[currentEpoch][token]
as users will not instantly claim all rewards. Additionally, it is wrong to assume that this comment "Update amount of non-alchemic-token revenue received for this epoch" is true because it could be that no rewards are received. This is easily proven by a test you provided already. All I did was to add
in the middle of it. You will see that the test will fail because of "Not enough revenue to claim" because it will now claim the "rewards" of two epochs, i.e., the epochRevenues[currentEpoch][token]
increased by 2x the contract balance. The difference is clearly visible when considering that rewards added to alchemic-tokens are those funds received via an exchange of tokens (i.e., the amount can also be 0) vs. non-alchemic are simply increased by the token balance at time of checkpoint()
-execution. This will break the whole reward calculation for non-alchemic tokens.
The fix would be to correctly track rewards for non-alchemic tokens by calculating the difference of actually received tokens vs. balance & claims. I haven't found any variables helpful for such a calculation so it may require rewriting the contract in order to fix this.
Please correct me if I am wrong.
Best RandomSec
(PS: I will add my wallet address later)
Proof of Concept
PoC 2: More custom, proving claims of multiple accounts are not calculated correctly. In that PoC you see that it says the same amount as reward for all 3 epochs even though no epoch has given any rewards
Last updated