Summary
Malicious attacker can steal all funds in claimAllRewards(), claimSingleReward() by reentrancy attack
Vulnerability Details
An attacker can re-enter the contract by these functions. They can call claimAllRewards
,claimSingleReward
several times before the balance is updated.
Impact
Attacker can perform a reentrancy attack and claim rewards while the balance exists.
Tools Used
Manual review
Recommendations
function claimAllRewards() public nonReentrant {
uint256 totalValue = 0;
for (uint256 i = 0; i < rewardsOwned[msg.sender].length; i++) {
totalValue += rewardsOwned[msg.sender][i].value;
}
require(totalValue > 0, "No rewards to claim");
delete rewardsOwned[msg.sender];
(bool success,) = payable(msg.sender).call{value: totalValue}("");
require(success, "Transfer failed");
}
function claimSingleReward(uint256 _index) public {
require(_index <= rewardsOwned[msg.sender].length, "Invalid index");
uint256 value = rewardsOwned[msg.sender][_index].value;
require(value > 0, "No reward to claim");
delete rewardsOwned[msg.sender][_index];
(bool success,) = payable(msg.sender).call{value: value}("");
require(success, "Transfer failed");
}