### Summary
The `transferReward()` function in the protocol allows users to transfer rewards to any address, including the zero address (`0x0000000000000000000000000000000000000000`). Transferring rewards to the zero address is dangerous as it can lead to rewards being permanently lost. Adding a zero address check can prevent this issue, ensuring that rewards are only transferred to valid addresses.
### Vulnerability Details
The current implementation of the `transferReward()` function does not validate the recipient address (`_to`). This means that a user or malicious actor could transfer rewards to the zero address, effectively burning them and making them irretrievable. The function allows this because there is no check for the zero address before the transfer occurs:
```solidity
function transferReward(address _to, uint256 _index) public {
require(_index < rewardsOwned[msg.sender].length, "Invalid index");
rewardsOwned[_to].push(rewardsOwned[msg.sender][_index]);
delete rewardsOwned[msg.sender][_index];
}
```
### Impact
• Lost Rewards: Transferring rewards to the zero address results in them being permanently lost. This can cause user frustration and weaken the integrity of the reward distribution system.
• Protocol Safety: Ensuring that rewards are only transferred to valid, non-zero addresses will prevent accidental or malicious loss of rewards. This change would protect the system without introducing any side effects.
### Tools Used
• Manual code review
### Recommendations
To prevent the transfer of rewards to the zero address, it is recommended to add a validation check in the transferReward() function. This will ensure that rewards can only be transferred to valid addresses.Updated trasnferreward() function would look like follows(along with accounting for issue with `delete` keyword which is submitted as a different vulnerability).
```diff
function transferReward(address _to, uint256 _index) public {
require(_index < rewardsOwned[msg.sender].length, "Invalid index");
+ require(_to != address(0), "Cannot transfer to the zero address");
rewardsOwned[_to].push(rewardsOwned[msg.sender][_index]);
// Move the last element into the place of the one being deleted
uint256 lastIndex = rewardsOwned[msg.sender].length - 1;
if (_index != lastIndex) {
rewardsOwned[msg.sender][_index] = rewardsOwned[msg.sender][lastIndex];
}
// Remove the last element
rewardsOwned[msg.sender].pop();
}
```