Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: medium
Invalid

Denial of Service vulnerabilty in ThePredicter::`cancelRegistration` Function Due to Unhandled Failed `call`

Relevant GitHub Links

https://github.com/Cyfrin/2024-07-the-predicter/blob/main/src/ThePredicter.sol#L62-L70

Summary

Denial of service for players attempting to cancel their registration if the call to refund the entrance fee fails. Affected users will not be able to cancel their registration, resulting in frustration and potential loss of funds.The vulnerability in the cancelRegistration function arises from the line:

require(success, "Failed to withdraw");

This can cause a vulnerability if the call to msg.sender fails, leading to the entire transaction being reverted. As a result, the player's status is not reverted to Pending, leading to potential denial of service for that player.

Vulnerability Details

In the cancelRegistration function, the player’s status is immediately set to Canceled before confirming that the call to refund the entrance fee was successful. If the refund call fails, the player’s status remains Canceled, even though they did not receive their refund. This results in an inconsistency where the player is marked as canceled but did not get their entrance fee back.

function cancelRegistration() public {
if (playersStatus[msg.sender] == Status.Pending) {
(bool success, ) = msg.sender.call{value: entranceFee}("");
@> require(success, "Failed to withdraw");
playersStatus[msg.sender] = Status.Canceled;
return;
}
revert ThePredicter__NotEligibleForWithdraw();
}

Impact

The vulnerability can lead to a denial of service for players trying to cancel their registration. If the call fails, those players are unable to cancel their registration and get their entrance fee back and the affected users will face issues, leading to user dissatisfaction and potential trust issues.

Tools Used

Manual Review

Recommendations

  • To handle the potential call failure in the cancelRegistration function and ensure the player's status is consistently managed, we should only update the status to Canceled after successfully returning the entrance fee to the player. This way, the player's status accurately reflects their registration status only when the refund process is successful.

function cancelRegistration() public {
if (playersStatus[msg.sender] == Status.Pending) {
(bool success, ) = msg.sender.call{value: entranceFee}("");
- require(success, "Failed to withdraw");
+ if (!success) {
+ revert("Failed to withdraw");
+ }
playersStatus[msg.sender] = Status.Canceled;
return;
}
revert ThePredicter__NotEligibleForWithdraw();
}
Updates

Lead Judging Commences

NightHawK Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.