In the ERC20RebaseDistributor contract, the distribute function is designed to distribute tokens proportionately to all rebasing accounts. However, there is a potential issue where anyone can dilute rewards by distributing a minimal amount of tokens (1 wei).
The root cause of this issue lies in the distribute function. When a distribution is made, the endTimestamp is simply extended up to block.timestamp + DISTRIBUTION_PERIOD , which means the current distribution is extended. This allows for a scenario where an attacker could repeatedly distribute a minimal amount of tokens (1 wei), diluting the rewards for other users.
A large distribution is ongoing (as an example, halfway through DISTRIBUTION_PERIOD), with many users set to receive a significant amount of tokens.
An attacker, who has a minimal amount of tokens (1 wei), calls the distribute function.
Because the endTimestamp is simply extended up to DISTRIBUTION_PERIOD in each distribute call, the attacker's distribution dilutes the rewards that were intended for the other users (in this case, halving them in all future blocks).
The attacker can carry out this attack repeatedly, such that the rewards are never fully distributed.
Tools Used
Manual review
Recommended Mitigation Steps
A more comprehensive solution could involve interpolating rewards individually for each distribution. This would mean that each distribution, which should be of DISTRIBUTION_PERIOD duration, would have its rewards calculated separately. This would prevent the dilution of rewards when a new distribution is made before the end of the current distribution period. However, the gas costs imposed by such an implementation could be prohibitively high, making this an unrealistic solution in practice.
Additionally, the distribute function could be restricted to being only callable by the ProfitManager. This would not directly fix the issue of reward dilution, but it would prevent a direct attack as per the example scenario. This would add an additional layer of security, as only the ProfitManager would be able to call the distribute function and potentially dilute rewards.
Lines of code
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/main/src/tokens/ERC20RebaseDistributor.sol#L364
Vulnerability details
Impact
In the
ERC20RebaseDistributor
contract, thedistribute
function is designed to distribute tokens proportionately to all rebasing accounts. However, there is a potential issue where anyone can dilute rewards by distributing a minimal amount of tokens (1 wei).The root cause of this issue lies in the
distribute
function. When a distribution is made, theendTimestamp
is simply extended up toblock.timestamp + DISTRIBUTION_PERIOD
, which means the current distribution is extended. This allows for a scenario where an attacker could repeatedly distribute a minimal amount of tokens (1 wei), diluting the rewards for other users.https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/main/src/tokens/ERC20RebaseDistributor.sol#L364
Proof of Concept
Consider the following scenario:
DISTRIBUTION_PERIOD
), with many users set to receive a significant amount of tokens.distribute
function.endTimestamp
is simply extended up toDISTRIBUTION_PERIOD
in eachdistribute
call, the attacker's distribution dilutes the rewards that were intended for the other users (in this case, halving them in all future blocks).Tools Used
Manual review
Recommended Mitigation Steps
A more comprehensive solution could involve interpolating rewards individually for each distribution. This would mean that each distribution, which should be of
DISTRIBUTION_PERIOD
duration, would have its rewards calculated separately. This would prevent the dilution of rewards when a new distribution is made before the end of the current distribution period. However, the gas costs imposed by such an implementation could be prohibitively high, making this an unrealistic solution in practice.Additionally, the
distribute
function could be restricted to being only callable by theProfitManager
. This would not directly fix the issue of reward dilution, but it would prevent a direct attack as per the example scenario. This would add an additional layer of security, as only theProfitManager
would be able to call thedistribute
function and potentially dilute rewards.Assessed type
Other