Skip to content
Last updated: March 11, 2025

SCWE-036: Inadequate Gas Limit Handling

Stable Version v0.0.1

This content is in the version-(v0.0.1) and still under active development, so it is subject to change any time (e.g. structure, IDs, content, URLs, etc.).

Send Feedback

Relationships

Description

Inadequate gas limit handling occurs when a contract fails to manage gas constraints efficiently, leading to performance bottlenecks and denial-of-service (DoS) risks. Poor gas handling can result in: - Unoptimized execution: Unnecessary gas-heavy computations increasing costs. - DoS vulnerabilities: Transactions failing due to excessive gas usage, blocking operations. - Inefficient batch processing: Overloaded loops or storage updates causing out-of-gas (OOG) errors.

Unlike SCWE-032, which focuses on the protocol-level block gas limit, this issue arises due to poor gas management at the smart contract level.

Remediation

  • Optimize gas usage: Minimize gas consumption in contract operations.
  • Avoid unbounded loops: Ensure loops have a fixed upper limit.
  • Test thoroughly: Conduct extensive testing to ensure operations stay within gas limits.

Examples

  • Inadequate Gas Handling
    pragma solidity ^0.8.0;
    
    contract InefficientProcessing {
        mapping(address => uint) public balances;
    
        function batchTransfer(address[] memory recipients, uint amount) public {
            for (uint i = 0; i < recipients.length; i++) {
                balances[recipients[i]] += amount; // Gas-intensive operation
            }
        }
    }
    

Issue: Processes large arrays in a single transaction, which can fail due to out-of-gas errors.

Why is this a problem? - If recipients.length is too large, the transaction fails. - Attackers can exploit this by submitting large recipient lists, causing a DoS attack.

  • Adequate Gas Handling
    pragma solidity ^0.8.0;
    
    contract GasOptimizedProcessing {
        mapping(address => uint) public balances;
    
        function batchTransfer(address[] memory recipients, uint amount) public {
            uint i = 0;
            while (i < recipients.length && gasleft() > 50000) { // Stop before out of gas
                balances[recipients[i]] += amount;
                i++;
            }
        }
    }
    
    ✔️ Fix: Uses gasleft() to gracefully exit before running out of gas, ensuring some transfers complete. Why is this better? ✅ Prevents complete transaction failure by handling only as many iterations as gas allows. ✅ Reduces DoS risk by allowing partial execution instead of reverting everything. ✅ Enables retrying to complete all operations over multiple calls.