Flow

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

Potential Denial of Service Due to Dust Attack Vulnerability in createAndDeposit Function

Summary

In a dust attack, an attacker floods the network or a specific smart contract with transactions carrying very small values. These transactions, often referred to as "dust," consume block space and network bandwidth, potentially leading to denial of service.

In Flow Sablier the docs states,One can create a flow stream without any upfront deposit, so the initial stream balance begins at zero. The sender can later deposit any amount into the stream at any time. An attacker could take an advantage and could create numerous streams and spam them and this could consume the storage of SablierFlow.sol contract.

Vulnerability Details

The Flow Sablier allows anyone to create a stream with no initial deposit or a very minimal deposit.

THe protocol maintains storage for each created stream e.g amount, ratePerSecond, recipient

A legitimate user typically creates a stream, funds it sufficiently, and allows the recipient to withdraw over time.

let's delve in how it can be exploited.

Bob repeatedly calls create to open streams targeting any recipient address, potentially even his own

Instead of funding each stream with a meaning amount , Bob supplies a dust amount a small fraction of a erc20 tokens

The protocol doesn’t enforce a minimum deposit, so these dust streams are accepted without issue

After creating each stream, Bob calls deposit with very small amount, just enough to be counted but not enough to be meaningful.

This action forces the SablierFlow.sol contract to handle storage updates for thousands of small deposits, further increasing storage bloat and clogging contract functionality.

Since each dust deposit is still processed by the SablierFlow.sol contract, this amplifies the strain on the system, creating further storage requirements and computation.

/// @inheritdoc ISablierFlow
function createAndDeposit(
address sender,
address recipient,
UD21x18 ratePerSecond,
IERC20 token,
bool transferable,
uint128 amount
)
external
override
noDelegateCall
returns (uint256 streamId)
{
// Checks, Effects, and Interactions: create the stream.
streamId = _create(sender, recipient, ratePerSecond, token, transferable);
// Checks, Effects, and Interactions: deposit on stream.
_deposit(streamId, amount);
}
/// @inheritdoc ISablierFlow
function deposit(
uint256 streamId,
uint128 amount,
address sender,
address recipient
)
external
override
noDelegateCall
notNull(streamId)
notVoided(streamId)
updateMetadata(streamId)
{
// Check: the provided sender and recipient match the stream's sender and recipient.
_verifyStreamSenderRecipient(streamId, sender, recipient);
// Checks, Effects, and Interactions: deposit on stream.
_deposit(streamId, amount);
}

Impact

Storage bloat

Tools Used

Manual

Recommendations

Set a minimum deposit amount : Require an initial deposit that meets a specified minimum threshold when a stream is created.

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.