Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: medium
Valid

Quadratic Gas Complexity in enterRaffle Function

Summary

The enterRaffle function in the provided smart contract contains a potential vulnerability related to inefficient loop handling, which can lead to excessively high gas costs and possible Denial of Service (DoS) attacks.

Vulnerability Details

The function allows multiple new players to be added to the players array through a single transaction. However, it performs a nested loop check for duplicate addresses. This nested loop results in quadratic time complexity (O(n²)), where n is the number of players. As the size of the players array grows, the gas cost for executing this function will increase significantly, potentially exceeding block gas limits and making the function unusable.

Impact

The impact of this inefficient loop handling includes:

  • High Gas Costs: Users may incur prohibitively high gas fees when the players array grows large.

  • Denial of Service: Malicious actors could exploit this vulnerability to perform a DoS attack by deliberately calling the function with numerous players, causing transactions to fail due to excessive gas costs.

  • Reduced Contract Usability: The contract's raffle feature may become unusable as the players array grows, impacting the overall functionality.

Tools Used

manual

Recommendations

To mitigate this issue, the following recommendations are provided:

  • Efficient Duplicate Check: Implement a more efficient way to check for duplicate entries, such as using a mapping to track addresses that have already entered the raffle.

  • Limit Player Count: Consider setting a reasonable limit on the number of new players that can be entered in a single transaction.

  • Regular Testing: Conduct regular tests and audits, especially after making changes to the contract logic.

POC

function testCanEnterRaffleManyGas() public {
address[] memory new_players = new address[](300);
for (uint256 i; i<300; i++){
new_players[i] = address(300+i);
}
puppyRaffle.enterRaffle{value: entranceFee * 300}(new_players);
address[] memory players = new address[](2);
players[0] = playerOne;
players[1] = playerTwo;
puppyRaffle.enterRaffle{value: entranceFee * 2}(players);
}
Updates

Lead Judging Commences

Hamiltonite Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

denial-of-service-in-enter-raffle

Support

FAQs

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