Insufficient Gas Griefing walkthrough

Insufficient gas griefing attacks are a subset of griefing attacks that particularly affect smart contracts performing external calls without validating the success return value. In this attack, the attacker provides a limited gas amount to execute solely the internal function logic, neglecting to provide enough gas for any potential external calls. If the contract lacks mechanisms to verify the success of external function calls or fails to assess the required gas amount for sub-calls, it proceeds as though no issues occurred. However, this poses significant risks.

Consider the contract below:

The "relay" function in the "CustomRelayer" contract takes a bytes parameter, marks it as executed in the "executed" mapping, and then initiates an external call to the "CustomTarget" contract without verifying its success.

If an attacker supplies an insufficient amount of gas, adequate only to set the bytes' execution status to true but not for the external call, the contract continues execution without detecting the failure. While this attack may not directly benefit the attacker, it introduces grief for the contract owner by generating a list of "executed" bytes that weren't actually executed.

Consider another contract below:

The provided sample contract neglects to verify the success of the external call, simply continuing execution regardless. Consequently, after dispatch function execution, the supplied data is flagged as executed in the executed mapping, preventing further submissions of the same data.

In this case, a forwarder invokes `dispatch` with minimal gas, enough for the CustomForwarder contract to execute successfully but inadequate for the external call. This results in a revert due to an out-of-gas error. Consequently, the user's transaction remains unexecuted, leading to the invalidation of their signature.

How to Prevent Gas Griefing Vulnerabilities.

1. To ensure adequate gas supply, implement gas estimation for both the function and external calls using a "require" statement. Validate that the provided gas is ample to execute them.

2. Validate the return values of external calls, verifying they match the expected outcome.

3. Restrict relay transactions exclusively to trusted users by integrating an access control mechanism

Link to the article