Issue: The _withdraw function updates the user's rewards and then transfers the tokens to the user. This could lead to reentrancy attacks if the safeTransfer call invokes an external contract that re-enters the withdraw function.
Solution: Use the checks-effects-interactions pattern to mitigate reentrancy. You can use a reentrancy guard or move the state changes (updating user rewards and total rewards) before the token transfer.
Issue: In _updateRewardPerToken, the total staked amount is checked for zero, which is good; however, ensure this condition is always managed properly throughout the contract, especially if there are any external interactions that could lead to state inconsistencies.
Solution: Always validate that totalStaked is not zero before performing operations involving division.
Issue: Although Solidity 0.8.0 introduced built-in overflow and underflow checks, it's still important to verify logic around updating state variables. For instance, if userRewards[_account] is reduced incorrectly, it could lead to underflows.
Solution: Ensure that any subtraction involving userRewards does not result in a negative value.
Issue: The DistributeRewards event is emitted even if toDistribute is zero, which could lead to misleading logs.
Solution: Consider adding a condition to only emit the event if toDistribute is greater than zero.
Issue: The function distributeRewards is marked as public, but it might be better as external to save gas, given that it is intended to be called externally.
Solution: Change the visibility of distributeRewards from public to external if it is not intended to be called internally.
onTokenTransferIssue: The onTokenTransfer function calls distributeRewards without any gas limit considerations. If distributeRewards requires more gas than what is available in a single call, it could fail.
Solution: Ensure there is a proper gas limit or consider potential gas consumption.
Issue: The logic in withdrawableRewards could potentially lead to incorrect rewards being calculated if userRewardPerTokenPaid or rewardPerToken is not updated properly before this calculation.
Solution: Ensure that rewards are updated before calculating the withdrawable rewards.
Issue: The current error handling uses a single revert message for unauthorized senders, which might not provide enough context for debugging.
Solution: Use more descriptive error messages to provide clarity on why a transaction failed.
Issue: The constant 1e18 is used multiple times in the contract, which could reduce code readability and increase the risk of mistakes if the scale factor needs to change.
Solution: Define it as a constant variable to improve readability and maintainability.
Issue: Currently, the only access control in place is for the controller. Ensure that any future functions that require restricted access are properly secured.
Solution: Consider implementing an access control mechanism (like OpenZeppelin's Ownable or AccessControl) if further functions need restrictions.
While the contract structure is sound, addressing these potential vulnerabilities will enhance security and reliability. Regular audits and testing in a variety of scenarios will help identify any additional edge cases or security risks.
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.