President Elector

First Flight #24
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: medium
Valid

[M-01] Denial of Service via Unbounded Loops in selectPresident

Summary

The selectPresident function, in the RankedChoice contract contains unbounded loops that iterate over the entire list of voters and candidates. If the VOTERS array or the s_candidateList becomes excessively large, the function may exceed the gas limit, causing the transaction to revert and effectively halting the election process.

Vulnerability Details

  • Unbounded Iterations:

    • Voters Loop: The outer loop in selectPresident iterates over all voters in the VOTERS array.

      for (uint256 i = 0; i < VOTERS.length; i++) {
      ...
      }
  • Candidates Loop: The inner loops iterate over each voter's ranked candidates and the s_candidateList during the recursive selection process.

    for (uint256 j = 0; j < orderedCandidates.length; j++) {
    ...
    }
  • Gas Consumption:

    • As the number of voters (VOTERS.length) or candidates (s_candidateList.length) increases, the gas required to execute these loops grows linearly.

    • There is no imposed limit on the number of voters or candidates, making the contract susceptible to scenarios where the gas cost becomes prohibitive.

  • Potential Exploits:

    • An attacker could aim to inflate the VOTERS array size or the number of candidates, leading to failed executions of the selectPresident function.

    • This Denial of Service (DoS) would prevent the election process from concluding, disrupting the contract's intended functionality.

Impact

  • Election Process Halted: If selectPresident fails due to gas exhaustion, the election cannot proceed, preventing the selection of a new president.

  • User Frustration: Legitimate users may be unable to finalize elections, undermining trust in the voting system.

  • Resource Wastage: Repeated attempts to execute selectPresident under these conditions can lead to unnecessary gas expenditure.

Tools Used

  • Manual Code Review: Analyzed the structure and flow of the selectPresident function.

  • Static Analysis Tools: Utilized tools like Slither to detect potential loop-related vulnerabilities.

Recommendations

  • Impose Limits on Voters and Candidates:

    • Voters Limit: Restrict the maximum number of voters to a reasonable number that ensures selectPresident can execute within gas limits.

    uint256 public constant MAX_VOTERS = 1000;
    constructor(address[] memory voters) EIP712("RankedChoice", "1") {
    require(voters.length <= MAX_VOTERS, "Too many voters");
    VOTERS = voters;
    ...
    }
    • Candidates Limit: Similarly, limit the number of candidates that can be ranked to prevent excessive iterations.

uint256 public constant MAX_CANDIDATES = 10;
function rankCandidates(address[] memory orderedCandidates) external {
require(orderedCandidates.length <= MAX_CANDIDATES, "Too many candidates");
...
}
  • Implement Emergency Mechanisms:

    • Circuit Breaker: Introduce a mechanism to pause the contract in case of detected anomalies to prevent further exploitation.

      bool public paused = false;
      modifier whenNotPaused() {
      require(!paused, "Contract is paused");
      _;
      }
      function pauseContract() external onlyOwner {
      paused = true;
      }
      function selectPresident() external whenNotPaused {
      ...
      }
  • Gas Limit Checks:

    • Estimate Gas Usage: Before executing selectPresident, estimate the gas required and ensure it remains within acceptable limits.

    • Revert Early: Implement checks that revert the transaction early if anticipated gas consumption exceeds thresholds.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

A high number of candidates could cause an OOG

Support

FAQs

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

Give us feedback!