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.
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.
An indexer could close an allocation passing 0x0 as the POI to skip the rewards calculation.
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.