Closed howlbot-integration[bot] closed 2 months ago
Known issue around instability at era-change boundaries -- see page 47: https://github.com/reserve-protocol/protocol/blob/72fc1f6e41da01e733c0a7e96cdb8ebb45bf1065/audits/Trust%20Security%20-%20Reserve%20Audit%20Report%203_1_0.pdf
thereksfour marked the issue as unsatisfactory: Out of scope
Lines of code
https://github.com/code-423n4/2024-07-reserve/blob/3f133997e186465f4904553b0f8e86ecb7bbacbf/contracts/p1/StRSR.sol#L614-L623 https://github.com/code-423n4/2024-07-reserve/blob/3f133997e186465f4904553b0f8e86ecb7bbacbf/contracts/p1/StRSR.sol#L490-L499 https://github.com/code-423n4/2024-07-reserve/blob/3f133997e186465f4904553b0f8e86ecb7bbacbf/contracts/p1/StRSR.sol#L693-L695
Vulnerability details
Impact
When
stakeRate
is no longer secure,stRSR
can initiate a new era and draft era through theresetStakes()
function. However, this function only checks thestakeRate
, leaving an opportunity for attackers to exploitdraftRSR
.Considering that RSR exists as an over-collateralized asset for rToken, in the event of rToken price de-pegging, RSR stakers are likely to unstake in large quantities. Due to the
unstakingDelay
, a significant amount ofstakeRSR
would be treated asdraftRSR
. Moreover, when these users unstake, theirstRSR
is burned, resulting in a loss of voting rights.This situation can lead to a scenario where a small amount of
stRSR
with voting rights can influence a large amount ofdraftRSR
. Furthermore, whenstakeRSR
is low, it becomes easy to manipulate thestakeRate
. Attackers can exploit the vulnerability inresetStake()
, which only checksstakeRate
, to forcefully executeresetStakes()
and subsequentlybeginDraftEra()
. This action would cause a large amount ofdraftRSR
to be considered as distributablerewardsRSR
in the new Era, preventing stakers from withdrawing theirdraftRSR
.The potential impact of this vulnerability is severe:
Proof of Concept
Assume the stRSR contract initially has 1M DAI staked. Due to market volatility or discovery of a protocol bug, a large amount of funds are unstaked, leaving only 0.01 DAI staked in the protocol:
From the system's perspective, stakeRSR is 0.01, corresponding to 0.01 stRSR (assuming stakeRate is still FIX_ONE), while draftRSR is approximately 1M. Since draftRSR has already burned stRSR, this portion of funds has no voting rights.
An attacker donates 110,000 USDC to the stRSR contract, which will be treated as rewardsRSR.
Assuming rewardRatio is MAX_REWARD_RATIO (0.01), after approximately 1006 seconds (16 minutes 48 seconds), about 11,000 USDC will be
_payoutRewards()
, reducing the stakeRate to < 1e12.At this point, the attacker can stake some RSR to gain voting rights and force the
resetStakes()
proposal to pass.Due to beginDraftEra(), any Drafts that haven't been withdrawn in time will be treated as rewardsRSR in the new Era.
Users will never be able to withdraw their RSR again.
Further analysis reveals additional concerns:
a) Operator vulnerability: Since the Reserve project only provides a mechanism for creating stablecoins, anyone can be an operator, including potential attackers. This increases the risk of exploitation.
b) Easy manipulation with low stakeRSR: The less stakeRSR left in the protocol, the easier it is to manipulate. An attacker could even exploit this vulnerability immediately after protocol deployment by staking a minimal amount of RSR and donating RSR to keep the initial stakeRate low, facilitating subsequent attacks.
c) Profit motivation: Beyond purely malicious attacks, an attacker could profit from this exploit by staking a large amount of RSR in the new Era to receive the majority of rewards from
_payoutRewards()
.Tools Used
Manual Review
Recommended Mitigation Steps
Limit the maximum value of
unstakingDelay
. It should not exceed the minimum time required for a new proposal to be submitted and executed.Either modify resetStakes() to check both stakeRate and draftRate, or separate beginEra() and beginDraftEra() into different functions.
Require the protocol operator to stake a significant amount of RSR and set minimum stake requirement. This would substantially increase the threshold for manipulating the
stakeRate
, making the attack much more difficult and costly to execute.Assessed type
Governance