The withdraw function contains a mechanism for distributing RAAC rewards by calculating `(totalRewards * userDeposit) / totalDeposits;`. An attacker can exploit this to get rewards by depositing and withdrawing either in the same block or the latter block. This leads to the attacker getting risk free rewards which is meant for genuine users depositing in the protocol.
When a user deposits their rToken into a stability pool:
rToken gets transferred from user
deToken gets minted to user.
the mapping userDeposits[msg.sender] gets updated.
When withdrawing :
raacRewards gets calculated by calling the calculateRaacRewards(msg.sender)
subtracts the amount from userDeposits[msg.sender]
burns the deToken from msg.sender
transfers rToken and raacRewards to the user
The vulnerability lies in the calculateRaacRewards function:
Consider the following:
(For simplifying let the exchange rate be consistent and decimals be 18)
Alice deposit 100e18 rToken and gets back 100e18 deToken. Therefore deToken.totalSupply() = 100e18.
Some time passes and 10e18 RAAC token rewards gets accured.
Bob deposits 100e18 rToken to 100e18 deToken.
Bob immediately withdraws 100e18 deTokens. Per the calculateRaacRewards totalRewards=10e18, userDeposit=100e18, totalDeposits = 200e18.
(10e18 * 100e18) / 200e18 = 5e18 raac rewards tokens. Repeating the steps would gain Bob another 2.5, then 1.25 and so on.
Bob can do this multiple times to gain most of the rewards tokens with no risk leaving Alice with a small percent of the entitled tokens.
Attacker can steal most of the reward.
VS Code
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.