đź‘®
Contract Cops
  • Mastering Ethereum Book
    • What is ethereum?
    • Tokens
    • Oracles
    • Decenralized Applications(DApps)
    • The Ethereum virtual machine
    • Ethereum basics
    • Ethereum clients
    • Cryptography
    • Wallets
    • Transactions
    • Chapter 7 - Smart Contracts & Solidity
    • Side Notes
      • Tokens
      • Smart Contracts and Solidity
  • Cryptography
    • Ethereum Cryptography - Cheatsheet
    • Assymetric vs symmetric cryptography
    • ECDSA vs RSA
    • Elliptic curves and ECDSA
    • Sha-256 Example
    • Sha-256
    • What are the different steps in SHA-256?
  • Ethereum Blocks
    • Block Headers
  • Learning Solidity
    • Storage vs memory
    • Upgradeable contracts
      • Proxy pattern in smart contracts
  • PoS
    • Proof of stake
  • PoW
    • PoW
  • Tokens
    • ERC-1155
    • ERC20
  • Cryptonomics
    • Automated market makers
    • Collateral Tokens
    • Collateralized Stablecoin
    • Fiat currency
    • Liquidity pool
    • Open Position: Meaning and Risk in Trading
    • Slippage
    • Spot price
  • Common Attack Vectors
    • Checking access control
    • Access control issues on critical functions
    • Account Existence Check for low level calls
    • Account Existence Check
    • Common attacks with contract/EOA addresses
    • Arithmetic under/overflow
    • Assert Attack
    • Assert require revert
    • Assert Violation
    • Bad Interface DOS
    • Bad pragma and compiler
    • Block Timestamp Manipulation
    • Bypassing contract check
    • Code With No Effects
    • Code size check vulnerability
    • Constructors with Care
    • Default Visibilities
    • Delegatecall
    • Delegatecall
    • Denial of Service (DoS)
    • DoS with block gas limit
    • Entropy Illusion
    • External contract referencing
    • Flash Loan Attack
    • Floating Point and Precision
    • Function selector abuse
    • Function selector abuse
    • Smart contract gas griefing
    • Hash collision parameters
    • Hash Collisions With Multiple Variable Length Arguments
    • Imprecise arithmetic
    • Improper Array Deletion
    • Incorrect array deletion
    • Incorrect interface
    • Insufficient Gas Griefing
    • Loop through long arrays
    • Message call with hardcoded gas amount
    • Not enough gas for ether transfer
    • Precision Loss in Calculations
    • Oracle Manipulation
    • Public Burn Function
    • Read-only reentrancy
    • Race Conditions/Front Running
    • Reentrancy Attacks
    • Reentrancy
    • Requirement Violation
    • Right-To-Left-Override control character (U+202E)
    • Shadowing State Variables
    • Short Address / Parameter attack
    • Signature Malleability
    • Signature Replay
    • Transaction Order Dependence
    • Tx.Origin Authentication
    • Unchecked CALL Return Values
    • Unexpected ether
    • Uninitialized Storage Pointers
    • Unsafe Ownership Transfer
  • EIP's
    • EIP155
    • EIP55
  • PoW
    • Ethash
    • Scrypt - RFC 7914
  • Questions for self evaluation
    • Questions 23/04/2023 (Nr: 84)
    • Usability guide for questions
  • Frequently asked questions
    • What is the difference between transaction and message?
    • What is the use of a interface or function without implementation?
  • UsefulResources
Powered by GitBook
On this page
  • Vulnerability
  • How to detect gas griefing vulnerability
  • Prevention
  1. Common Attack Vectors

Insufficient Gas Griefing

PreviousIncorrect interfaceNextLoop through long arrays

Last updated 2 years ago

Insufficient gas griefing attacks can be performed on contracts that accept data and use it in a sub-call on another contract.

If the sub-call fails, either the whole transaction is reverted, or execution is continued.

In most cases, this results in uncontrolled behavior that could have a dangerous impact on the business logic.

In the case of a relayer contract, the user who executes the transaction, the 'forwarder', can effectively censor transactions by using just enough gas to execute the transaction, but not enough for the sub-call to succeed.

Vulnerability

This vulnerability exists in smart contracts that either do not check the required gas to execute a sub call, or does not check the returned value of the call itself.

Let's see an example:

Let’s suppose that the “Target” contract is the contract that the “Relayer” contract communicates with.

The relayer contract is the vulnerable contract. The vulnerability is one the line

(bool success, ) = address(target).call(abi.encodeWithSignature("execute()", _data));

There is no check of the remaining gas nor the result of the call, the function continues its execution without any problem.

This behavior can cause a serious impact on the application logic.

If you compile those two contracts and try to execute the relay function normally without increasing the gas limit asnd then you check the value of the result variable in the Target smart contract, you will notice that its value didn’t change.

Due to insufficient gas, the contract Target didn’t finish its execution correctly.

You can increase the gas limit and observe that the result variable value will be changed.

How to detect gas griefing vulnerability

Firstly, understand the business logic of the smart contract(s). Then start looking at operations that perform external communication without result verification.

Each time a contract sends, receive or even calls a smart contract function, there is a risk to find this vulnerability.

Prevention

Prevention of this vulnerability is one of the most difficult tasks.

Your first approach whould be to require the user to specify the gas to be sent to the Target contract. And if the gas is less than the submitted value, the transaction will revert.

Let's see an example:

But the problem is that the relayer may not revert as well if no gas was left for the execution of the Target contract.

In addition, the user may also forget or maliciously specify a _gasLimit that is enough to execute the Relayer contract but not to call the Target contract.

So there is a risk with this approach, let's find another solution:

estimatedGasValue

this variable represent the amount of gas required by the call() function to correctly execute the Target smart contract function.

gasNeededBetweenCalls 

this is the estimated gas cost

gasAvailable/64

this represents the amount of gas that will remain in the contract after calling the Target function. The 64 number comes from the fact that by default the smart contract leaves 1/64 of the amount of gas sent to the callee smart contract to allow the caller smart contract to finish its execution after that call finishes.

The steps are the following:

  1. firstly the contract calculates the amount of gas that will be available for the contract while reaching the call() function

  2. Then it checks if the amount of gas after deducing that value from the gas sent by the user will remain higher than the estimatedGasValue for the call()

In general, the idea here is that the developer is the one who precise how much gas should be sent and not the user.

NOTE: This solution is not perfect, as if the gas cost gets higher with time, the solution may fail. The best way to deal with this problem is by giving the EVM the ability to calculate the required gas for each call and revert the transaction if it is not sufficient.

Alt text
Alt text
Alt text