Flow

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

The `Sablier::_create` internal function should use `_safeMint` instead of `_mint`.

Description:

In the current implementation of the _create internal function, _mint is used instead of _safeMint. _safeMint checks that if the recipient is a contract, the receiver implements the onERC721Received hook to acknowledge that the contract is capable of receiving NFT to avoid loss of NFT ownership, however there is no such check in _mint, result in loss of NFT if the recipient is not designed to receive NFT.

https://github.com/Cyfrin/2024-10-sablier/blob/8a2eac7a916080f2022527408b004578b21c51d0/src/SablierFlow.sol#L610

Recommended Mitigation:

Would recommend the protocol to use _safeMint instead of _mint.

function _create(
address sender,
address recipient,
UD21x18 ratePerSecond,
IERC20 token,
bool transferable
)
internal
returns (uint256 streamId)
{
// Check: the sender is not the zero address.
if (sender == address(0)) {
revert Errors.SablierFlow_SenderZeroAddress();
}
uint8 tokenDecimals = IERC20Metadata(address(token)).decimals();
// Check: the token decimals are not greater than 18.
if (tokenDecimals > 18) {
revert Errors.SablierFlow_InvalidTokenDecimals(address(token));
}
// Load the stream ID.
streamId = nextStreamId;
_streams[streamId] = Flow.Stream({
balance: 0,
isStream: true,
isTransferable: transferable,
isVoided: false,
ratePerSecond: ratePerSecond,
sender: sender,
snapshotDebtScaled: 0,
snapshotTime: uint40(block.timestamp),
token: token,
tokenDecimals: tokenDecimals
});
unchecked {
// Effect: bump the next stream ID.
nextStreamId = streamId + 1;
}
- _mint({ to: recipient, tokenId: streamId });
+ _safeMint({ to: recipient, tokenId: streamId });
// REST OF CODE....
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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