Flow

Sablier
FoundryDeFi
20,000 USDC
View results
Submission Details
Severity: high
Invalid

Reentrancy Vulnerability in SablierFlow::depositAndPause Function can cause unauthorized access to funds

Summary

The depositAndPause function in the SablierFlow contract is vulnerable to reentrancy attacks. Due to the sequence of state updates and external calls within this function, an attacker could exploit this vulnerability to gain unauthorised access to funds or manipulate the contract’s state.

Vulnerability Details

The depositAndPause function in the SablierFlow contract contains a potential reentrancy vulnerability. The function calls _deposit and _pause sequentially, allowing for a possible reentrant attack during the token transfer in _deposit.

The vulnerability arises because:

  • _deposit makes an external call to token.safeTransferFrom().

  • _pause modifies state variables after the external call in _deposit.

  • An attacker could exploit this timing difference to manipulate the contract's state during the token transfer.

Impact

This could result in unauthorized access to funds or manipulation of the contract's state.
An attacker could exploit this vulnerability by:

  • Calling depositAndPause with a large amount of tokens.

  • During the token transfer in _deposit, executing another transaction that manipulates the state of the contract.

  • After the token transfer completes, calling pause again to freeze the funds.

Tools Used

  • Manual code review

  • Static analysis: Slither, aderyn, cloc

Recommendations

To mitigate this risk, consider implementing the following approach:
Update the states changes first before performing the transaction by making external call in _deposit.

// @audit re-entrancy error
function depositAndPause(
uint256 streamId,
uint128 amount
)
external
override
noDelegateCall
notNull(streamId)
notPaused(streamId)
onlySender(streamId)
updateMetadata(streamId)
{
// Checks, Effects, and Interactions: pause the stream.
_pause(streamId);
// Checks, Effects, and Interactions: deposit on stream.
_deposit(streamId, amount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.