Griefing attacks represent an exploit aimed at vulnerabilities in smart contracts, usually related to business logic. These attacks cause a negative impact on the operation of the smart contract system, despite providing no direct profit for the attackers. In some cases, griefing attacks may be deployed to disrupt overall system operations or to create disruption during specific critical moments.
Consider the following Solidity code, which illustrates a typical scenario for a griefing attack:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
This example demonstrates a DelayedWithdrawal contract. In the constructor, the beneficiary is set to the deployer's address along with a custom delay, for instance, 24 hours. Anyone can deposit funds, which become available for withdrawal and transfer to the beneficiary after the configured delay. However, each deposit must transfer a non-zero amount of ETH to the smart contract.
The potential for a griefing attack arises because anyone can call the
deposit function and reset the
lastDeposit timestamp. This allows a griefing attacker to transfer a minimal amount (e.g., 1 wei) to the smart contract, triggering a reset of the
lastDeposit timestamp. Consequently, this new
lastDeposit timestamp prevents the beneficiary from withdrawing their funds.
An attacker could deploy this strategy by submitting a transaction just before the end of the delay period to reset the timestamp. Alternatively, the attacker could engage in frontrunning, anticipating, and pre-empting the beneficiary's calls to the
withdraw function, thereby creating a more cost-effective denial-of-service attack.
Gas Griefing Attacks¶
Insufficient gas griefing attacks represent a subset of griefing attacks that primarily affect smart contracts performing external calls without checking the success return value. In such an attack, an adversary may supply just enough gas to ensure the top-level function's success while ensuring the external call's failure due to gas exhaustion. Owing to the 63/64 rule, the top-level contract can complete its function call, resulting in an incomplete state change. Such issues are particularly prevalent in smart contracts executing generic calls, including relayers and multisig wallets.
The following example, featuring a simplified relayer contract, illustrates the potential for an insufficient gas griefing attack:
1 2 3 4 5 6 7 8 9 10 11 12 13
Relayers are much more complex smart contract systems. The section on signature-related attacks contains more inspiration on how to break them!
Upon an external call failure within the
forward function, the contract has the choice of either reverting the entire transaction or continuing execution. The example contract provided does not check the success of the external call and simply continues execution. As a result, once the execution of the
forward function is complete, the submitted data is marked as executed in the
executed mapping, thereby preventing anyone from submitting the same data again.
Any third-party forwarder can invoke the
forward function to execute a user's transaction on their behalf. Suppose a forwarder calls
forward with minimal gas, sufficient only to allow the
Relayer contract to succeed but causing the external call to revert due to an out-of-gas error. In that case, the user's transaction is not executed, and their signature is invalidated. Consequently, the anticipated state change on the
target contract will not occur.
Malicious forwarders can exploit this technique to permanently censor user transactions within the
Relayer contract. Even though the adversary does not profit directly from this griefing attack, they can still disrupt the operations of the smart contract and inconvenience the victim.