The withdrawableRewards function in the RewardsPool contract suffers from precision loss when calculating rewards for users with very small stakes. This results in users with minimal stakes not receiving any rewards, even when rewards have been distributed to the pool.
The test case demonstrates that when a user stakes a very small amount and a small reward is distributed, the calculation of withdrawable rewards results in a value that rounds down to zero due to integer division in Solidity. This is evidenced by the passing test:
The test passes, confirming that withdrawableRewards returns 0 for the user with a minimal stake, even after rewards have been distributed to the pool.
Unfair Reward Distribution: Users with very small stakes may never receive rewards, even when they're entitled to them based on their proportional stake in the pool.
Discouragement of Small Stakers: This issue could discourage users from making small stakes, potentially reducing overall participation in the staking system and affecting the protocol's decentralization.
Accumulated Lost Rewards: Over time, this could lead to a non-trivial amount of rewards being effectively "lost" due to rounding errors, stuck in the contract and never distributed to any users.
Trust Issues: If users notice they're not receiving expected rewards for small stakes, it could lead to a loss of trust in the protocol.
Manual , Hardhat
To address this vulnerability, consider implementing one or more of the following solutions:
Increase Calculation Precision
Implement a Reward Accumulator
Set a Minimum Reward Threshold
Use Fixed-Point Arithmetic Libraries
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.