BribeRewarder contract funtionality is broken with low-decimals tokens.
Vulnerability Detail
The duration of a VotingPeriod is 14 days which is 1209600 in seconds. Also, a user can create a BribeRewarder which whatever token he likes and these kind of issues are in-scope according to the docs. In _calculateRewards of BribeRewarder, a division is executed and we can see it here :
Given the VotingPeriod duration of 1,209,600 seconds, any _amountPerPeriod less than 1,209,600 will result in emissionsPerSecond being 0 due to Solidity's rounding down behavior. This is particularly problematic for tokens with low decimal places, such as GUSD (Gemini Dollar), which has 2 decimals. For instance, if the _amountPerPeriod is 10,000 GUSD, the emissionsPerSecond will always be 0, preventing voters from receiving any rewards.
Impact
This vulnerability prevents the distribution of rewards to voters when using tokens with low decimal places. Consequently, the reward distribution mechanism is rendered ineffective, and voters do not receive the rewards they are entitled to for their participation.
To address this issue, consider implementing a check to ensure that the _amountPerPeriod is sufficient to generate a non-zero emissionsPerSecond for the given VotingPeriod duration. Additionally, consider adjusting the calculation method to accommodate tokens with low decimal places, ensuring accurate reward distribution. One potential solution is to use a higher precision for internal calculations to avoid rounding down to zero.
zarkk01
Medium
BribeRewarder
contract funtionality is broken with low-decimals tokens.Vulnerability Detail
The duration of a
VotingPeriod
is 14 days which is 1209600 in seconds. Also, a user can create aBribeRewarder
which whatever token he likes and these kind of issues are in-scope according to the docs. In_calculateRewards
ofBribeRewarder
, a division is executed and we can see it here :Given the VotingPeriod duration of 1,209,600 seconds, any _amountPerPeriod less than 1,209,600 will result in emissionsPerSecond being 0 due to Solidity's rounding down behavior. This is particularly problematic for tokens with low decimal places, such as GUSD (Gemini Dollar), which has 2 decimals. For instance, if the _amountPerPeriod is 10,000 GUSD, the emissionsPerSecond will always be 0, preventing voters from receiving any rewards.
Impact
This vulnerability prevents the distribution of rewards to voters when using tokens with low decimal places. Consequently, the reward distribution mechanism is rendered ineffective, and voters do not receive the rewards they are entitled to for their participation.
Code Snippet
https://github.com/sherlock-audit/2024-06-magicsea/blob/main/magicsea-staking/src/rewarders/BribeRewarder.sol#L300
Tool used
Manual Review
Recommendation
To address this issue, consider implementing a check to ensure that the _amountPerPeriod is sufficient to generate a non-zero emissionsPerSecond for the given VotingPeriod duration. Additionally, consider adjusting the calculation method to accommodate tokens with low decimal places, ensuring accurate reward distribution. One potential solution is to use a higher precision for internal calculations to avoid rounding down to zero.
Duplicate of #545