# GIP-0003: Accumulated subgraph rewards reset to zero on edge case

**URL:** <https://forum.thegraph.com/t/gip-0003-accumulated-subgraph-rewards-reset-to-zero-on-edge-case/1537>\
**Category:** Graph Improvement Proposals (GIP)\
**Tags:** protocol-gov\
**Created:** [February 23, 2021, 3:36pm UTC](https://forum.thegraph.com/t/gip-0003-accumulated-subgraph-rewards-reset-to-zero-on-edge-case/1537 "2021-02-23T15:36:07Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ari](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.thegraph.com/ari/32/2747_2.png) [@ari](https://forum.thegraph.com/u/ari)\
**Post date:** [February 23, 2021, 3:36pm UTC](https://forum.thegraph.com/t/gip-0003-accumulated-subgraph-rewards-reset-to-zero-on-edge-case/1537/1 "2021-02-23T15:36:07Z")

</div>

### Description

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.

### Implementation

> <https://github.com/graphprotocol/contracts/pull/452>
>
> \### Description
> The RewardsManager contract main responsibility is to calculate… rewards accrued for allocations based on the total token supply, tokens signalled on subgraphs, accumulated rewards on a subgraph and allocations. Under certain edge condition the calculation could fail and block closing an allocation that would collect rewards.
> 
> \### Problem
> There is a particular edge case that happens when there are running allocations on a subgraph deployment ID, the total amount of curation signal is removed back to zero and \`closeAllocation()\` is called by an indexer. 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.
> 
> \### Solution
> By removing the early check within \`getAccRewardsForSubgraph()\` that returns zero for the subgraph accumulated rewards when the signal is zero we will always return the accumulated amount, as it should be an ever increasing number.
> 
> \### Additional Changes
> \- Check that rewards \> 0 before minting
> \- Linting differences
> \- Improve some comments

---

<div class="post-metadata">

**Author:** ![ari](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.thegraph.com/ari/32/2747_2.png) [@ari](https://forum.thegraph.com/u/ari)\
**Post date:** [March 10, 2021, 2:10pm UTC](https://forum.thegraph.com/t/gip-0003-accumulated-subgraph-rewards-reset-to-zero-on-edge-case/1537/2 "2021-03-10T14:10:10Z")

</div>

Community voting is up on Snapshot →   
[https://snapshot.page/#/graphprotocol.eth/proposal/Qmd1kNg7wMUVaL62wQrCwTnno6rmFHt85zMa5f5SGss186](https://snapshot.page/#/graphprotocol.eth/proposal/Qmd1kNg7wMUVaL62wQrCwTnno6rmFHt85zMa5f5SGss186)

---

<div class="post-metadata">

**Author:** ![ari](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.thegraph.com/ari/32/2747_2.png) [@ari](https://forum.thegraph.com/u/ari)\
**Post date:** [April 21, 2021, 12:15am UTC](https://forum.thegraph.com/t/gip-0003-accumulated-subgraph-rewards-reset-to-zero-on-edge-case/1537/3 "2021-04-21T00:15:19Z")

</div>

The contract changes have been audited by OpenZeppelin, you can see the full report on this link.

> **[The Graph RewardsManager Upgrade Audit](https://blog.openzeppelin.com/the-graph-rewardsmanager-upgrade-audit/)**
>
> The Graph team found an edge case condition in which the amount of accumulated rewards retrieved from the \`RewardsManager\` for a specific signal can be zero.

---

<div class="post-metadata">

**Author:** ![Brandon](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.thegraph.com/brandon/32/1265_2.png) [@Brandon](https://forum.thegraph.com/u/Brandon)\
**Post date:** [May 7, 2021, 9:48pm UTC](https://forum.thegraph.com/t/gip-0003-accumulated-subgraph-rewards-reset-to-zero-on-edge-case/1537/4 "2021-05-07T21:48:43Z")

</div>

Update: the improvement described here (GIP-0003) was approved by The Graph Council in [Graph Governance Proposal-0002](https://snapshot.org/#/council.graphprotocol.eth/proposal/QmcXadW4qroQs2tMwn8Re1vfLhxnECNGaXr8axggjgNR5e).

Subsequently, the upgrade was completed in [this transaction](https://etherscan.io/tx/0x97b22fc12ce47c037528d92c66c9b3e37888a4766a03e7932eec754bf8519431). Everything appears healthy and no issues have been reported as a result of the upgrade.
