The function withdrawMaxAndTransfer withdraws and transfers streamID and it calls the internal transfer function which transfers amount instead of the streamID.
`function withdrawMaxAndTransfer(
uint256 streamId,
address newRecipient
)
external
override
noDelegateCall
notNull(streamId)
{
// Check: the caller is the current recipient. This also checks that the NFT was not burned.
address currentRecipient = _ownerOf(streamId);
if (msg.sender != currentRecipient) {
revert Errors.SablierV2Lockup_Unauthorized(streamId, msg.sender);
}
// Skip the withdrawal if the withdrawable amount is zero.
uint128 withdrawableAmount = _withdrawableAmountOf(streamId);
if (withdrawableAmount > 0) {
withdraw({ streamId: streamId, to: currentRecipient, amount: withdrawableAmount });
}
// Checks and Effects: transfer the NFT.
_transfer({ from: currentRecipient, to: newRecipient, tokenId: streamId });
}`
`function _transfer(address from, address to, uint256 amount) internal virtual {
_balances[from] = _balances[from] - amount;
_balances[to] = _balances[to] + amount;
emit Transfer(from, to, amount);
}`
As seen from above, internal function will transfer amount instead of streamID
Instead of transferring streamID, amount is transferred which is incorrect.
Manual Review
Transfer streamID instead of amount
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.