The RewardsManager contract’s primary responsibility is to calculate rewards accrued for allocations based on time, the total token supply, tokens signaled on subgraphs, accumulated rewards on a subgraph, and allocations. Under specific edge conditions, the calculation could fail, making a closing allocation that would collect rewards to revert.
Problem
There is a particular edge case in the rewards calculation process under the following sequence:
A Subgraph is curated.
There are running allocations on that Subgraph.
The total amount of curation tokens is removed back to zero by burning ALL the signal.
An indexer calls closeAllocation() on an allocation related to the Subgraph.
If this happens, the indexer won’t be able to close that allocation unless it is opting for no rewards by sending POI=0x0. The reason for this is that getAccRewardsForSubgraph() is reseting the accumulated rewards for a subgraph when the curation pool is empty. The consequence is that subgraph.accRewardsForSubgraphSnapshot can be larger than subgraph.accRewardsForSubgraph leading to a revert when calculating new accrued rewards.
Workaround
An indexer could close an allocation passing 0x0 as the POI to skip the rewards calculation.
Solution
Remove the early check within getAccRewardsForSubgraph() that returns zero for the subgraph accumulated rewards when the signal is currently zero. That way, the function will always return the accrued amount, as it should be an ever-increasing number.