Skip to content

Latest commit

 

History

History
52 lines (26 loc) · 2.03 KB

056.md

File metadata and controls

52 lines (26 loc) · 2.03 KB

Interesting Mulberry Eagle

Medium

ETH Transfer Failure Due to Insufficient Gas Stipend

Summary

The sendETHToTreasury() function in the StreamEscrow contract uses call{value: amount}() this, which transfers ETH, but it does not provide a sufficient gas stipend. This leads to failed ETH transfers when the recipient contract needs more than the default 2300 gas. This makes the whole transaction revert, and hence, the functions forwardAll(), fastForwardStream(), and createStream() are unusable under certain conditions.

Root Cause

No response

Internal pre-conditions

No response

External pre-conditions

No response

Attack Path

  1. Alice makes a call to the forwardAll() function, forwarding all pending ETH streams to Bob.

  2. In the function it is first checked if minimumTickDuration has passed since the last forward. If it hasn't, then it silently returns without doing anything.

  3. If the time elapsed is adequate, Alice updates the lastForwardTimestamp and goes ahead to call the function sendETHToTreasury(), transferring ethStreamedPerTick (1 ETH in our example) to Bob.

  4. Bob's contract contains logic such as emitting events or updating storage, that uses a lot more than the base 2300 gas stipend. That will cause the transfer to fail.

  5. The failure causes the entirety of Alice's forwardAll() transaction to revert, thus preventing Bob from getting the ETH and disrupting the funds flow as intended.

Impact

These functions become unusable when handling large amounts of ETH or complex recipient logic. It will often result in failed transactions and operations, causing blocked critical transfers to the treasury.

PoC

No response

Mitigation

Update the call invocation to include a sufficient gas stipend or a dynamic gas allocation:

(bool sent, ) = ethRecipient.call{ value: amount, gas: customGasLimit }('');