Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OlaHamid - **Denial of Service (DoS) via Excessive Gas Consumption in warmUpSettlementState IN THE NounsAuctionHouseV2 AND NounsAuctionHouseV2.sol CONTRACTS ** #175

Open
sherlock-admin2 opened this issue Nov 30, 2024 · 0 comments

Comments

@sherlock-admin2
Copy link

sherlock-admin2 commented Nov 30, 2024

OlaHamid

Medium

**Denial of Service (DoS) via Excessive Gas Consumption in warmUpSettlementState IN THE NounsAuctionHouseV2 AND NounsAuctionHouseV2.sol CONTRACTS **

Summary:

The warmUpSettlementState function in NounsAuctionHouseV2 AND NounsAuctionHouseV2.sol can be exploited to create a Denial of Service (DoS) condition by consuming excessive gas. This occurs when a large range of IDs is passed as parameters, causing the function to iterate over a significant number of elements. This can result in the gas required to execute the transaction exceeding the block gas limit, rendering the function unusable.


Vulnerability Details:

  1. Location:

    • File: NounsAuctionHouseV2.sol AND NounsAuctionHouseV3.sol
    • Line: 350
  2. Description:

    • The warmUpSettlementState function contains a for loop iterating from startId to endId. When endId - startId is excessively large, the gas required exceeds the block gas limit (~30M gas on Ethereum Mainnet), causing the transaction to fail.
    • This vulnerability can be exploited to disrupt the intended functionality of warming up settlement slots, potentially impacting auctions or related processes.
  3. Proof of Concept (PoC):

    • copy and paste this in the NounAuctionHouseV3.t.sol A test was written to simulate a large range of settlement states being warmed up:
      uint256 largeStartId = 0;
      uint256 largeEndId = 20000; // Large range to simulate DoS attempt
      uint256 gasBefore = gasleft();
      auction.warmUpSettlementState(largeStartId, largeEndId);
      uint256 gasAfter = gasleft();
      console.log("Gas used for large range:", gasBefore - gasAfter);
    • Gas used: 883,180,016, far exceeding the block gas limit.
  4. Impact:

    • This vulnerability allows an attacker to disrupt the functionality of the warmUpSettlementState function by exploiting gas limitations, leading to a Denial of Service condition.

Recommendations: These are some of the recommendation to fix the vulnerability, Any or multiple of the following should be fine.

  1. Restrict Range Size:
    • Introduce a check to limit the range (endId - startId) to a safe value that ensures gas usage remains within block gas limits:
+      error maxGasLimitError();
+      // this can be flexible depending on the dev choise settings
+      uint256 MAX_BATCH_SIZE = 5000;

          function warmUpSettlementState(uint256 startId, uint256 endId) external {
+            require(endId - startId <= MAX_BATCH_SIZE, "Range too large");
        for (uint256 i = startId; i < endId; ++i) {
            // Skipping Nounder rewards, no need to warm up those slots since they are never used.
            // this keyword continue, is weird... 
            // o think this next line is protecting from a DOS attack
            if (i <= 1820 && i % 10 == 0) continue;
            

            SettlementState storage settlementState = settlementHistory[i];
            if (settlementState.blockTimestamp == 0) {
                settlementState.blockTimestamp = 1;
                settlementState.slotWarmedUp = true;
            }

        }
  1. Implement a more stricter Batching:

  2. Add Gas Safety Checks:

    • Monitor gas usage within the loop and break early if the remaining gas drops below a safe threshold:
+      error maxGasLimitError();
+      //this can be flexible depending on the dev choise settings
+      uint256 public constant SAFE_GAS_THRESHOLD = 20_000_000;

          function warmUpSettlementState(uint256 startId, uint256 endId) external {
        for (uint256 i = startId; i < endId; ++i) {
            // Skipping Nounder rewards, no need to warm up those slots since they are never used.
            // this keyword continue, is weird... 
            // o think this next line is protecting from a DOS attack
            if (i <= 1820 && i % 10 == 0) continue;
            

            SettlementState storage settlementState = settlementHistory[i];
            if (settlementState.blockTimestamp == 0) {
                settlementState.blockTimestamp = 1;
                settlementState.slotWarmedUp = true;
            }
+            if (gasleft() < SAFE_GAS_THRESHOLD) revert maxGasLimitError();
        }
@sherlock-admin4 sherlock-admin4 changed the title Generous Peanut Platypus - **Denial of Service (DoS) via Excessive Gas Consumption in warmUpSettlementState IN THE NounsAuctionHouseV2 AND NounsAuctionHouseV2.sol CONTRACTS ** OlaHamid - **Denial of Service (DoS) via Excessive Gas Consumption in warmUpSettlementState IN THE NounsAuctionHouseV2 AND NounsAuctionHouseV2.sol CONTRACTS ** Dec 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant