Flow

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

Zero Rate Stream Creation Vulnerability

Summary

The SablierFlow contract allows the creation of streams with a ratePerSecond of zero. This can lead to the creation of non-functional streams, where no funds are transferred, potentially causing confusion and misuse of the contract.

Vulnerability Details

The issue arises from the absence of a validation check for ratePerSecond in the _create function. This allows streams to be created with a zero rate, which is not practical for a streaming payment system.

function _create(
address sender,
address recipient,
UD21x18 ratePerSecond,
IERC20 token,
bool transferable
) internal returns (uint256 streamId) {
// Missing validation for ratePerSecond > 0
...
}
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.22;
import "forge-std/src/Test.sol";
import "../src/SablierFlow.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MockERC20 is ERC20 {
constructor() ERC20("Mock Token", "MTK") {
_mint(msg.sender, 1000000 * 10 ** decimals());
}
}
contract SablierFlowTest is Test {
SablierFlow sablierFlow;
MockERC20 token;
address sender = address(0x1);
address recipient = address(0x2);
function setUp() public {
token = new MockERC20();
sablierFlow = new SablierFlow(sender, IFlowNFTDescriptor(address(0)));
token.approve(address(sablierFlow), type(uint256).max);
}
function testCreateStreamWithZeroRatePerSecond() public {
vm.startPrank(sender);
// Attempt to create a stream with ratePerSecond set to zero
uint256 streamId = sablierFlow.create(
sender,
recipient,
ud21x18(0), // ratePerSecond set to zero
token,
true
);
// Use the getter function or public mapping to access the stream data
Flow.Stream memory stream = sablierFlow.getStream(streamId);
assertEq(stream.sender, sender, "Stream should be created with the correct sender");
assertEq(stream.ratePerSecond.unwrap(), 0, "Rate per second should be zero");
vm.stopPrank();
}
}

Impact

  • Streams with a zero rate do not transfer any funds, leading to non-functional streams.

  • Creating and managing such streams consumes blockchain resources without providing any utility.

Tools Used

  • Manual review

  • Foundry

Recommendations

Add a validation check in the _create function to ensure that ratePerSecond is greater than zero.

function _create(
address sender,
address recipient,
UD21x18 ratePerSecond,
IERC20 token,
bool transferable
) internal returns (uint256 streamId) {
// Check: the ratePerSecond must be greater than zero
+ if (ratePerSecond.unwrap() <= 0) {
+ revert Errors.SablierFlow_InvalidRatePerSecond();
}
// Existing logic for stream creation
...
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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