fix(curation): count curator fees in the network signal total - #336
MoonBoi9001 wants to merge 7 commits into
Conversation
Curator fees paid into a curation pool raised each deployment's signal but not totalTokensSignalled, so the total fell behind by every fee ever paid: 1,801,315 GRT on Arbitrum by 2026-09-25.
The fee test only had a pool with no GNS signal. This one gives the GNS contract a quarter of a pool and checks it takes a quarter of the fees as auto-migrating signal.
A deployment grafted from a version that left curator query fees out of totalTokensSignalled inherits a total short by exactly the fees paid so far, so add them back once and record it.
Lint flagged these imports as unused in files this branch already touches.
Network signal is split into GRT curated through the GNS contract and GRT curated directly. Adding past fees to the total alone left the 2 parts 1,801,315 GRT short of it on Arbitrum, so the GNS part is reset to what its shares are worth and direct gets the rest. L1 is unchanged.
The one-time step that adds back past curator fees walks every pool the GNS contract curates. Saving straight away stops each later handler in the same block from repeating that walk.
Removes 3 commented-out helper functions, shortens 2 comments that ran long, and wraps 2 test lines that were wider than the formatter's 100-character limit.
| let graphNetwork = GraphNetwork.load('1')! | ||
| countPastCurationFeesInSignal(graphNetwork) | ||
| return graphNetwork | ||
| } |
There was a problem hiding this comment.
I'd rather keep this as it was, instead of adding a graft specific calculation.
As mentioned via Slack, grafting long term is an antipattern, so we can (and should) always assume we are indexing the data from scratch :)
| // Versions that left curation fees out of totalTokensSignalled fell short by exactly the fees paid, | ||
| // and a graft inherits that, so add them back once and re-split the total by the value of the GNS | ||
| // contract's shares. Not on L1, which subtracts signal sent to L2 twice, so this would not match. | ||
| function countPastCurationFeesInSignal(graphNetwork: GraphNetwork): void { |
| graphNetwork.save() | ||
| } | ||
|
|
||
| function splitSignalByGnsShareValue(graphNetwork: GraphNetwork): void { |
| graphNetwork.totalTokensSignalled = BigInt.fromI32(0) | ||
| graphNetwork.totalTokensSignalledAutoMigrate = BigDecimal.fromString('0') | ||
| graphNetwork.totalTokensSignalledDirectly = BigDecimal.fromString('0') | ||
| graphNetwork.curationFeesInSignalTotal = true |
|
|
||
| graphNetwork.save() | ||
| } | ||
| countPastCurationFeesInSignal(graphNetwork) |
| graphNetwork: GraphNetwork, | ||
| deployment: SubgraphDeployment, | ||
| fees: BigInt, | ||
| ): void { |
There was a problem hiding this comment.
I don't exactly remember if this is still an issue with graph node, but at some point in order for graph-node to properly update your entities when modifying them in a separate function, you had to return the "new" updated entity, and reassign them to your variable. I'm like 95% sure this doesn't happen anymore, but potentially worth checking. I'll explain in the next line.
| graphNetwork.totalCuratorQueryFees = graphNetwork.totalCuratorQueryFees.plus( | ||
| event.params.curationFees, | ||
| ) | ||
| addCurationFeesToNetworkSignal(graphNetwork, deployment, event.params.curationFees) |
There was a problem hiding this comment.
As mentioned above, at some point, you used to need to do this:
graphNetwork = addCurationFeesToNetworkSignal(graphNetwork, deployment, event.params.curationFees)
Or graph node would not properly save the modifications done in the addCurationFeesToNetworkSignal function.
Unsure if that's still a thing, but worth mentioning.
| graphNetwork.totalCuratorQueryFees = graphNetwork.totalCuratorQueryFees.plus( | ||
| event.params.curationFees, | ||
| ) | ||
| addCurationFeesToNetworkSignal(graphNetwork, deployment, event.params.curationFees) |
There was a problem hiding this comment.
Same as the last comment
| graphNetwork.totalCuratorQueryFees = graphNetwork.totalCuratorQueryFees.plus( | ||
| event.params.tokensCurators, | ||
| ) | ||
| addCurationFeesToNetworkSignal(graphNetwork, deployment, event.params.tokensCurators) |
There was a problem hiding this comment.
Same as the last comment
| "Whether totalTokensSignalled, and on Arbitrum its auto-migrating and direct parts, include every curator query fee paid into curation pools. Unset only on a deployment grafted from a version that left them out, until its next update adds them" | ||
| curationFeesInSignalTotal: Boolean |
Motivation
When an indexer collects query fees, a cut goes into that deployment's curation pool. That adds GRT to the pool without creating new shares, so every curator's shares become worth more. The subgraph was adding that GRT to the deployment's own
signalledTokensbut not to the network-widetotalTokensSignalled, so the network total fell further behind with every fee paid.This PR counts curator query fees in
totalTokensSignalledand its auto-migrating and direct split. A deployment grafted from an earlier version adds the fees it missed back to the total once and, on Arbitrum, re-splits it by the current value of the GNS contract's shares. Those fees raised each deployment's signal but not the network total, which had fallen behind by 1,801,315 GRT on Arbitrum by 2026-09-25.