https://github.com/Cyfrin/2024-10-sablier/blob/8a2eac7a916080f2022527408b004578b21c51d0/src/SablierFlow.sol#L728-L733
According to the documentation, a stream should be voidable by the sender, recipient, or an approved third party. However, in the SablierFlow.sol::_void function, an if statement incorrectly requires the msg.sender to be both the sender and either the recipient or an approved third party. Since msg.sender cannot simultaneously be the sender, recipient, and an approved third party, this check effectively blocks authorized parties from voiding the stream. Using an || operator instead of && would correctly check if msg.sender is either the sender, recipient, or an approved third party.
```solidity
if (msg.sender != _streams[streamId].sender && !_isCallerStreamRecipientOrApproved(streamId)) {
revert Errors.SablierFlow_Unauthorized({ streamId: streamId, caller: msg.sender });
}
```
Streams cannot be voided, potentially leaving them active indefinitely, which disrupts protocol functionality and results in undeletable streams.
Manual Review, VSCode
Replace the && operator with || to ensure that any authorized party (sender, recipient, or approved third party) can void the stream as intended.
```solidity
function _void(uint256 streamId) internal {
if (msg.sender != _streams[streamId].sender || !_isCallerStreamRecipientOrApproved(streamId)) {
revert Errors.SablierFlow_Unauthorized({ streamId: streamId, caller: msg.sender });
}
uint256 debtToWriteOff = _uncoveredDebtOf(streamId);
if (debtToWriteOff == 0) {
uint256 ongoingDebtScaled = _ongoingDebtScaledOf(streamId);
if (ongoingDebtScaled > 0) {
_streams[streamId].snapshotDebtScaled += ongoingDebtScaled;
}
} else {
_streams[streamId].snapshotDebtScaled = Helpers.scaleAmount({ amount: _streams[streamId].balance, decimals: _streams[streamId].tokenDecimals });
}
_streams[streamId].snapshotTime = uint40(block.timestamp);
_streams[streamId].ratePerSecond = ud21x18(0);
_streams[streamId].isVoided = true;
emit ISablierFlow.VoidFlowStream({
streamId: streamId,
sender: _streams[streamId].sender,
recipient: _ownerOf(streamId),
caller: msg.sender,
newTotalDebt: _totalDebtOf(streamId),
writtenOffDebt: debtToWriteOff
});
}
```
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.