Open code423n4 opened 1 year ago
Interesting finding. Its valid but the bug would actually result in the protocol retaining more capital due to reporting lower APRs than it should.
0xScotch marked the issue as sponsor confirmed
Picodes marked the issue as satisfactory
Lines of code
https://github.com/code-423n4/2023-02-malt/blob/main/contracts/RewardSystem/RewardThrottle.sol#L445-L455 https://github.com/code-423n4/2023-02-malt/blob/main/contracts/RewardSystem/RewardThrottle.sol#L576
Vulnerability details
Impact
RewardThrottle.checkRewardUnderflow()
might calculate the cumulativeAPR
s for epochs wrongly.As a result,
cashflowAverageApr
will be calculated incorrectly inupdateDesiredAPR()
, andtargetAPR
would be changed unexpectedly.Proof of Concept
In
checkRewardUnderflow()
, it calls a_sendToDistributor()
function to update cumulativeAPR
s after requesting some capitals from the overflow pool.The main reason for this issue is that
_sendToDistributor()
doesn't update the cumulativeAPR
s whenamount == 0
and the below scenario would be possible.activeEpoch = 100
andepoch = 103
. It's possible if the active epoch wasn't updated for 2 epochs.checkRewardUnderflow()
function will call_fillInEpochGaps()
and the cumulativeAPR
s will be settled accordingly.overflowPool
and increase the rewards for epochs.balance
fromoverflowPool
and increases the cumulativeAPR
s for epoch 101 correctly in_sendToDistributor()
.overflowPool
doesn't have any remaining funds and thebalance(At L450)
will be 0 for epochs 101, 102._sendToDistributor()
will be terminated right away and won't increase the cumulativeAPR
s of epoch 102 according to epoch 101 and this value won't be changed anymore because theactiveEpoch
is 103 already.As a result, the cumulative
APR
s will save smaller values from epoch 102 andcashflowAverageApr
will be smaller also if thesmoothingPeriod
contains such epochs inupdateDesiredAPR()
.So the
updateDesiredAPR()
function will change thetargetAPR
using the smaller average value and the smoothing logic wouldn't work as expected.Tools Used
Manual Review
Recommended Mitigation Steps
I think
_sendToDistributor()
should update the cumulativeAPR
s as well whenamount == 0
.