Closed howlbot-integration[bot] closed 3 months ago
To mitigate this vulnerability, the calculation of stakeRSRToTake and draftRSRToTake should be based on the proportion of rsrAmount to the total RSR in the contract before the seizure
This is how it's currently coded.
The provided mitigation code is the one that contains the bug of dividing by the post-seizure amount. The preSeizureBalance
variable is definitely the balance after the seizure.
I believe line 4 in the PoC is the incorrect one.
The seizeRSR() function calculates stakeRSRToTake as: (500 * 100 + 9999) / 10000 = 55 (rounded up)
No: (500 * 100 + 9999) / 10000 = 5.9999 = 5 (rounded down)
thereksfour marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2024-07-reserve/blob/3f133997e186465f4904553b0f8e86ecb7bbacbf/contracts/p1/StRSR.sol#L424-L479
Vulnerability details
Description
The
StRSRP1
contract contains a critical vulnerability in itsseizeRSR()
function that allows theBackingManager
to seize more RSR than intended. This function is designed to allow theBackingManager
to seize a specified amount of RSR from the contract, adjusting thestakeRSR
anddraftRSR
balances accordingly. However, the current implementation uses the total RSR balance of the contract (rsrBalance
) in its calculations, which can be manipulated to skew the results.The core issue lies in the calculation of
stakeRSRToTake
anddraftRSRToTake
. These values are computed using the following formulas:The problem arises because
rsrBalance
includes the amount of RSR that is being seized (rsrAmount
). This means that if an attacker were to transfer additional RSR to the contract immediately before callingseizeRSR()
, they could artificially inflatersrBalance
, leading to an incorrect calculation of the amounts to be seized.For example, if the contract initially has 1000 RSR, and the
BackingManager
attempts to seize 100 RSR, the calculation would be based on a total balance of 1000 RSR. However, if an attacker transfers an additional 9000 RSR to the contract just before the seizure, the calculation would now be based on a total balance of 10,000 RSR, significantly altering the proportion of RSR seized from each pool.Impact
It allows the
BackingManager
to seize more RSR than intended, which can lead to significant financial loss and instability in the system. An attacker could manipulate thersrBalance
by transferring RSR to the contract just before callingseizeRSR()
, leading to incorrect calculations and potentially allowing theBackingManager
to seize more RSR than intended.Proof of Concept
stakeRSR
and 500 indraftRSR
.BackingManager
prepares to seize 100 RSR by callingseizeRSR(100)
.seizeRSR()
function calculatesstakeRSRToTake
as:(500 * 100 + 9999) / 10000 = 55
(rounded up)draftRSRToTake
is calculated as 55.stakeRSR
= 445,draftRSR
= 445, instead of the expected 450 each.Tools Used
Manual review
Recommended Mitigation Steps
To mitigate this vulnerability, the calculation of
stakeRSRToTake
anddraftRSRToTake
should be based on the proportion ofrsrAmount
to the total RSR in the contract before the seizure, rather than includingrsrAmount
in the denominator. Here's the recommended fix:This change ensures that the calculation is based on the pre-seizure balance, preventing manipulation through last-minute RSR transfers to the contract.
Assessed type
Other