Gas Limit Vulnerability

Unbounded loops in Solidity smart contracts can create significant vulnerabilities, one of the most notable being the ‘Out of Gas’ vulnerability. This issue arises when a loop runs for an indeterminate or excessively high number of iterations, consuming more gas than a block’s gas limit, and causing transactions to fail. In this tutorial, we will dissect this vulnerability, understand its implications, and explore strategies to mitigate its risks.

Understanding the Vulnerability

In Ethereum, every operation, including computations and storage modifications, consumes gas. When a function with an unbounded loop is called, the loop might execute numerous iterations, each consuming gas. If the total gas consumption surpasses the block gas limit, the transaction will fail, potentially locking funds or rendering contract functionalities inoperable.

Examples of Vulnerabilities:

  • A function within a contract iterates through an array or list. If this array becomes excessively large, iterating over it could consume gas past the block limit.

  • An attacker manipulates the contract, intentionally increasing the number of iterations a loop must perform, making certain contract functions unusable.

Implications of the ‘Out of Gas’ Vulnerability

  • Denial of Service (DoS): Functions susceptible to this vulnerability can be rendered unusable, causing service disruptions.

  • Locked Funds: If a function responsible for funds withdrawal is affected, users might be unable to withdraw their assets, resulting in locked funds.

  • Manipulation by Attackers: Malicious actors could exploit this vulnerability to manipulate contract behavior, disrupting normal operations.

Real World Examples:

[M-10] Unbounded loop in withdraw() may cause rewards to be locked in the contract - code4rena

The withdraw() has an unbounded loop with external calls. If the gas costs of functions change between when deposits are made and when rewards are withdrawn, or if the gas cost of the deposit (transferFrom()) is less than the gas cost of the withdrawal (transfer()), then the withdraw() function may revert due to exceeding the block size gas limit.

[M-20] massUpdatePools() is susceptible to DoS with block gas limit - unbounded loop - code4rena

massUpdatePools() is a public function and it calls the updatePool() function for the length of poolInfo. Hence, it is an unbounded loop, depending on the length of poolInfo.

If poolInfo.length is big enough, block gas limit may be hit.

Last updated