Submitted by hyh
There is no check for the reward token amount to be transferred out in stashRewards(). As reward token list is external (controlled with IGauge(gauge).reward_tokens), and an arbitrary token can end up there, in the case when such token doesnt allow for zero amount transfers, the stashRewards() managed extra rewards retrieval can become unavailable.
I.e. stashRewards() can be blocked for even an extended period of time, so all other extra rewards gathering will not be possible. This cannot be controlled by the system as pool reward token list is external.
Setting the severity to medium as reward gathering is a base functionality of the system and its availability is affected.
stashRewards() attempts to send the amount to rewardArbitrator() without checking:
https://github.com/code-423n4/2022-05-vetoken/blob/2d7cd1f6780a9bcc8387dea8fecfbd758462c152/contracts/ExtraRewardStashV2.sol#L193-L203
If IStaker(staker).withdraw() produced no new tokens for any reason, the amount = amount.sub(before) above can be zero:
https://github.com/code-423n4/2022-05-vetoken/blob/2d7cd1f6780a9bcc8387dea8fecfbd758462c152/contracts/ExtraRewardStashV2.sol#L188-L189
As reward token can be arbitrary, it can also be reverting on an attempt to transfer zero amounts:
https://github.com/d-xo/weird-erc20#revert-on-zero-value-transfers
If this be the case then the whole stashRewards() call will be failing until IStaker(staker).withdraw() manage to withdraw some tokens or such token be removed from gauges reward token list. Both events arent directly controllable by the system.
Consider running the transfer only when amount is positive:
jetbrain10 (veToken Finance) confirmed 
Alex the Entreprenerd (judge) commented:
