Skip to content

fix: track indexing issuance through the IssuanceAllocator (GIP-0089) - #334

Open
PaulieB14 wants to merge 2 commits into
graphprotocol:masterfrom
PaulieB14:fix/gip-0089-issuance-allocator
Open

fix: track indexing issuance through the IssuanceAllocator (GIP-0089)#334
PaulieB14 wants to merge 2 commits into
graphprotocol:masterfrom
PaulieB14:fix/gip-0089-issuance-allocator

Conversation

@PaulieB14

@PaulieB14 PaulieB14 commented Sep 3, 2026

Copy link
Copy Markdown

Problem

GraphNetwork.networkGRTIssuancePerBlock has reported 120.73 GRT/block on Arbitrum since GIP-0089 activated on 2026-09-01, when the rate the RewardsManager actually issues at became 96.584. The schema documents this field for reward-rate maths ("To get annual rate do (networkGRTIssuancePerBlock * blocksPerYear)"), so every consumer computing indexing-reward APR from it currently overstates by 120.73 / 96.584 = exactly 1.25x.

Reproducible

Same block-scoped query either side of the change (GIP-0089 took effect at Arbitrum block 500,701,945, between them):

{
  before: graphNetwork(id: "1", block: { number: 500600000 }) { networkGRTIssuancePerBlock }
  after:  graphNetwork(id: "1", block: { number: 501148942 }) { networkGRTIssuancePerBlock }
}

Both return 120730000000000000000. A fifth of issuance was redirected in between and the field is byte-identical.

On chain at the same moment:

contract call returns
RewardsManager 0x971B9d3d…a525 getAllocatedIssuancePerBlock() 0xe208d721 96.584e18
RewardsManager 0x971B9d3d…a525 issuancePerBlock() 0x6c080f18 120.730e18
IssuanceAllocator 0xb64f29b2…1a7e getTargetAllocation(RewardsManager).selfMintingRate 96.584e18

Cause

Two independent causes, either sufficient on its own:

  1. Wrong getter. rewardsManager.ts read issuancePerBlock(). Once the IssuanceAllocator was wired up (GIP-0076 / GIP-0088) the RewardsManager mints only its own allocation, and that legacy storage slot stopped being the rate it issues at. getAllocatedIssuancePerBlock() was also absent from abis/RewardsManagerStitched.json, so the mapping could not have called it.

  2. No trigger. The value is only refreshed by the RewardsManager's ParameterUpdated('issuancePerBlock'). GIP-0089 changed the split on the allocator, so no such event fired and the field was never re-read.

Changes

  • New IssuanceAllocator data source handling TargetAllocationUpdated(address,uint256,uint256). When the target is the RewardsManager, newSelfMintingRate is the rate it will issue at — the event carries the value, so no contract call is needed. This is the only place a future re-split is observable: GIP-0088 Phase 3 moves a further 6 GRT/block to the Recurring Agreement Manager, taking the RewardsManager to 90.584, and would otherwise go unnoticed the same way.
  • rewardsManager.ts prefers getAllocatedIssuancePerBlock(), via try_ so it still works on deployments predating the upgrade where the getter is absent.
  • abis/RewardsManagerStitched.json gains the two getters it was missing.
  • The allocator address resolves from @graphprotocol/address-book, which required bumping 1.1.0 -> ^1.3.0: 1.1.0 neither ships issuance/addresses.json nor exports the path, while 1.3.0 exports "./*/addresses.json". It is deployed on Arbitrum One and Arbitrum Sepolia only and resolves empty elsewhere, matching how subgraphService is handled.

Verification

  • yarn prepare:arbitrum and yarn prepare:arbitrum-sepolia both resolve the allocator (0xb64f29b2… / 0x76a0d756…)
  • yarn build compiles
  • The CI test-prep step (testAddressesL1/L2 + mustache) still produces a valid config/addresses.ts on both layers

Note for reviewers

Picking up the 2026-09-01 allocation requires reindexing from a start block at or before it, since the handler is event-driven. Whether that warrants a resync of the deployed subgraphs is a maintainer call.

I targeted master since that is where recent PRs (#332, #333) merged; the README still points contributors at mainnet-staging, which was last updated in 2024. Happy to retarget.

`GraphNetwork.networkGRTIssuancePerBlock` has read 120.73 GRT/block on Arbitrum
since GIP-0089 activated on 2026-09-01, when the rate the RewardsManager
actually issues at became 96.584. Every consumer computing indexing-reward APR
from this field — the schema documents it for exactly that — currently
overstates by 120.73/96.584 = 1.25x.

Two independent causes, either sufficient on its own:

1. WRONG GETTER. rewardsManager.ts read `issuancePerBlock()`. Once the
   IssuanceAllocator was wired up (GIP-0076/GIP-0088) the RewardsManager mints
   only its own allocation, and that legacy storage slot stopped being the rate
   it issues at. On Arbitrum One today the slot still returns 120.73e18 while
   `getAllocatedIssuancePerBlock()` returns 96.584e18. The getter was also
   absent from abis/RewardsManagerStitched.json, so the mapping could not have
   called it.

2. NO TRIGGER. The value is only refreshed by the RewardsManager's
   `ParameterUpdated('issuancePerBlock')`. GIP-0089 changed the split on the
   ALLOCATOR, so no such event was emitted and the field was never re-read.

Reproducible — the same block-scoped query either side of the change:

  {
    before: graphNetwork(id:"1", block:{number:500600000}) { networkGRTIssuancePerBlock }
    after:  graphNetwork(id:"1", block:{number:501148942}) { networkGRTIssuancePerBlock }
  }

Both return 120730000000000000000. GIP-0089 took effect at Arbitrum block
500,701,945, between them.

On chain at the same moment:
  RewardsManager 0x971B9d3d0Ae3ECa029CAB5eA1fB0F72c85e6a525
    getAllocatedIssuancePerBlock()  0xe208d721  ->  96.584e18
    issuancePerBlock()              0x6c080f18  -> 120.730e18
  IssuanceAllocator 0xb64f29b2d81140ffc3a135e319561a1bd03b1a7e
    getTargetAllocation(RewardsManager).selfMintingRate -> 96.584e18

CHANGES

- New IssuanceAllocator data source handling
  `TargetAllocationUpdated(address,uint256,uint256)`. When the target is the
  RewardsManager, `newSelfMintingRate` is the rate it will issue at, so the
  event carries the value and no contract call is needed. This is the only
  place a future re-split is observable: GIP-0088 Phase 3 moves a further
  6 GRT/block to the Recurring Agreement Manager, taking the RewardsManager to
  90.584, and would otherwise go unnoticed in the same way.
- rewardsManager.ts prefers `getAllocatedIssuancePerBlock()`, via try_ so it
  still works on deployments predating the upgrade where the getter is absent.
- abis/RewardsManagerStitched.json gains the two getters it was missing.
- The allocator address is resolved from @graphprotocol/address-book, which
  required bumping 1.1.0 -> ^1.3.0: 1.1.0 neither ships issuance/addresses.json
  nor exports the path, while 1.3.0 exports "./*/addresses.json". It is
  deployed on Arbitrum One and Arbitrum Sepolia only, and resolves empty
  elsewhere, matching how subgraphService is handled.

VERIFIED

`yarn prepare:arbitrum` and `yarn prepare:arbitrum-sepolia` both resolve the
allocator (0xb64f29b2… and 0x76a0d756… respectively) and `yarn build` compiles.
The CI test-prep step (testAddressesL1/L2 + mustache) still produces a valid
config/addresses.ts on both layers.

Note for reviewers: picking up the 2026-09-01 allocation requires reindexing
from a start block at or before it, since the handler is event-driven. Whether
that warrants a resync of the deployed subgraphs is a maintainer call.
CI caught this: `Path: dataSources > 9 > source > address / Contract address is
invalid` on both L1 and L2 test prep. I had used an empty string as the
placeholder on networks without an allocator, but graph-cli requires 40 hex
characters and every other absent contract in these fixtures — subgraphService,
graphPayments, paymentsEscrow, graphTallyCollector — uses the zero address.

Verified by running the exact CI steps rather than assuming: testAddressesL1
and testAddressesL2 both now complete mustache + codegen, and the matchstick
suite passes 88/88.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant