code-423n4 / 2024-07-reserve-findings

5 stars 4 forks source link

RToken can manipulate distribution to avoid paying DAO fees #53

Open c4-bot-6 opened 3 months ago

c4-bot-6 commented 3 months ago

Lines of code

https://github.com/code-423n4/2024-07-reserve/blob/3f133997e186465f4904553b0f8e86ecb7bbacbf/contracts/p1/Distributor.sol#L204-L227 https://github.com/code-423n4/2024-07-reserve/blob/3f133997e186465f4904553b0f8e86ecb7bbacbf/contracts/p1/Distributor.sol#L240

Vulnerability details

Revenue produced by RTokens is sold for both RSR and RTokens according to a distribution defined in the Distributor. The BackingManager splits the collateral tokens to be sold proportionately to the RSR/RToken distribution ratio and sends them to the rsrTrader and rTokenTrader. When trades settle, the obtained RSR or RTokens are sent to the Distributor, which distributes them no longer according to the RSR/RToken ratio but to the different destinations for the specific token. The sum of all destinations for each token is used to derive the ratio.

The DAO fee is added to the RSR share of the initial split and paid when RSR is distributed.

However, the current implementation allows governance to manipulate the distribution settings without much effort in a way that can significantly reduce the amount of DAO fees paid.

This can be achieved through a combination of two different root causes:

Essentially, the distribution can be set in a way that temporarily accumulates RSR revenue in in the rsrTrader according to one RSR/RToken ratio, and then later redistributed with a different ratio.

Impact

RTokens can avoid paying most of the DAO fee

Proof of Concept

Assuming a 10% DAO fee, governance can execute the following steps to pay only about 1% in fees:

  1. Set the distribution such that rsrTotal == 0 before DAO fees are added.
  2. Add the RSR token itself as a distribution target. Like stRSR, RSR does not allow transferring to itself, so the distribution will always fail.
  3. 10% of revenue will accumulate as RSR in the rsrTrader.
  4. After some time, change the distribution such that rTokenTotal == 0 and add another destination with non-zero rsrDist (e.g., stRSR).
  5. Remove RSR as a distribution target and call rsrTrader.distributeTokenToBuy().
  6. Only 10% of the accumulated RSR will go to the DAO, which is effectively 1% of the total revenue.
  7. Repeat this process as needed.

Tools Used

Manual review

Recommended Mitigation Steps

Disallowing RSR as a distribution token prevents this to a large extent.

Assessed type

Other

thereksfour commented 2 months ago

Will try to get the sponsor's opinion, and will set it to valid before the sponsor responds. It's about Malicious Governance, though it actually compromises the DAO, so it's probably a privilege escalation.

c4-judge commented 2 months ago

thereksfour marked the issue as satisfactory

c4-judge commented 2 months ago

thereksfour marked the issue as selected for report

akshatmittal commented 2 months ago

This is a known issue, changing Distributions in a specific way can change what is actually paid out to veRSR. See publicly known issues as well as the Trust report specifically.

tbrent commented 2 months ago

The way I'm seeing it: a new finding (RSR self-entries in the distributor table cause distribution to revert) raises the previously known issue TRST-L-2 in severity from L to M, due to what is effectively privilege escalation by avoiding paying the DAO fee.