Submitted by cmichel, also found by GeekyLumberjack, kenzo, pedroais, and hyh
The Streaming contract allows recovering the reward token by calling recoverTokens(rewardToken, recipient).
However, the excess amount is computed incorrectly as ERC20(token).balanceOf(address(this)) - (rewardTokenAmount + rewardTokenFeeAmount):
Note that rewardTokenAmount only ever increases (when calling fundStream) but it never decreases when claiming the rewards through claimReward.
However, claimReward transfers out the reward token.
Therefore, the rewardTokenAmount never tracks the contracts reward balance and the excess cannot be computed that way.
Assume no reward fees for simplicity and only a single user staking.
Reward token recovery does not work.
The claimed rewards need to be tracked as well, just like the claimed deposits are tracked.
I think you can even decrease rewardTokenAmount in claimReward because at this point rewardTokenAmount is not used to update the cumulativeRewardPerToken anymore.
brockelmore (Streaming Protocol) confirmed
