Accounting Implications On The Graph Protocol

Mackenzie Patel
Mackenzie Patel
save time
September 28, 2023

Related articles

Browse all articles

Accounting Implications On The Graph Protocol

September 28, 2023
Protocol

Dubbed “The Google of Blockchains,” The Graph is a complex, utility-based protocol that houses reams of blockchain data. Querying squeeth contracts on Opyn or LP tokens on Curve is doable through the army of Graph indexers (aka validators) underpinning the protocol. The Graph is definitely one of the more difficult protocols to wrap your head around since there’s so many moving parts - curators signal on subgraphs, fishermen submit disputes and delegators stake their tokens to indexers. The indexers - really the powerhouse of The Graph - index “subgraphs” or open APIs that anyone can create, test, and query. It’s a dynamic, bamboozling web that is both a technical and accounting challenge.

This article will highlight the main accounting gray areas on The Graph, ranging from revenue cutoff issues to accurately reporting token vesting schedules. My knowledge on The Graph is still a work in progress, and new revelations about its design and functionality still occur daily. It’s a never-ending rabbit hole of data just waiting to be indexed.

But First, What are Allocations?

The concept of “allocations” is unique to The Graph and serves as the mechanism behind deciding what subgraphs to index. At any given point, an indexer has a certain amount of GRT tokens delegated to it from outside parties or from the self-bond1 provided by the indexer. These GRT tokens are then “allocated” to subgraphs depending on the expected rewards of that subgraph and the curation signal2. Once the tokens have been allocated, the indexer gets to work whipping up the data requested in the subgraph. The allocated tokens aren’t digitally moving anywhere - they’re more akin to weights or a signal that Indexer X is working on Subgraph Y.

Opening and closing allocations is a technical process and requires a seasoned web3 engineer to decide what allocations to index, the optimal duration of the allocation3, and the trade off between rewards and the gas cost to execute indexing. It looks simple on Graphscan.io, but the innards of The Graph are mind-boggling. There’s also a concept called “Proof of Indexing” (POI) which verifies the indexer is grabbing data for the subgraphs they allocated to. A POI must be submitted before an indexer can claim their rewards.

To break it down, head to the Prime-2 indexer on Graphscan. There’s two sections: delegator and indexer. One address can serve as both a delegator to different indexers and as an indexer itself. Prime-2 is delegating to itself (and Blockdaemon previously) and has continuously been earning delegation rewards on their stake.

The more interesting part is the indexers though - head to the “allocations” tab to see all the current and previous allocations on various subgraphs, ranging from Art Blocks to SushiSwap. You can see the amount of allocated GRT, estimated & actual indexer rewards, POI (proof of indexing)4, hashes, and more. After the engineer closes allocations, there’s a dispute period of 56 epochs where anyone can submit a dispute about the quality of the data provided. Assuming the data is accurate, the indexer and its delegators receive rewards and a proportion of query fees generated by the subgraph.

Understanding allocations is pivotal to detangling the accounting issues present in the protocol. The Graph is so complex that the Foundation even established a virtual academy for it (their docs and video tutorials are phenomenal!).

Accounting Mysteries on The Graph

#1 Revenue Cutoff Issues with Indexer Rewards

An engineer has flexibility with opening and closing allocations5, which means their allocations can cross different months and years. Let’s say our indexing engineer opens twenty subgraph allocations on March 25th and doesn’t close them until April 15th. The actual token revenue lands in your wallet on approx April 22nd, when the dispute period has officially ended and GRT tokens are awarded. The indexer was performing work from March 25th - March 31st, but unless the accountant is Graph-savvy and has been accruing, the revenue is subject to a cut-off risk.

Accounting for crypto in general tends to lean towards cash basis versus accrual accounting. It’s baked in the nature of the blockchain: tokens are recorded on the ledger only when they digitally move, not because some off-chain performance obligation has been fulfilled. Crypto accounting software also tends to “sync” in transactions as they occur, so all accruals made are manual and time-consuming.

Luckily for accountants, estimating the allocation rewards at a point in time isn’t rocket science. Head to your indexer, navigate to the allocations tab, and click on the dubious question mark that appears under “indexer rewards” for open allocations. Graphscan has been known to implode at times, but this measure at least gives some indication of your accrued rewards. If your effective fee differs from your stated rewards cut6, you can back into your actual indexer rewards earned with this formula:

(indexer rewards / stated rewards cut) * effective fee

An Alternative Method for all the Accountant Programmers

A more precise method is to call the getrewards() function on the Graph Rewards Contract via Etherscan. To begin, paste the following code into The Graph playground and execute. Replace “indexer id” with the ID of your indexer (typically the 0x address on your main indexer page).

query indexerAllocations {
  indexer(id: "0x6125ea331851367716bee301ecde7f38a7e429e7") {
    allocations {
      activeForIndexer {
        allocations {
          id
        }
      }
    }
  }
}

The playground will list the ids of all the active allocations for your indexer. Grab the first ID and head to the rewards contract on Etherscan. Under function 9 GetRewards(), enter your first allocation id and hit “query” to get the pending rewards. Etherscan will display the number in a long-winded uint256 format, so divide by 10^18 to get the human-readable version. To calculate the total amount of rewards across all allocations, each allocation ID will need to be checked (if you couldn’t tell, this process is practically begging for automation).

💡 Note: the contract call will display total rewards (indexer + delegator), so if you’re looking solely for indexer rewards, multiply the total rewards by the effective fee cut % for that allocation.

Another related issue is the query fee rebates. Query fees are nuanced because all fees generated by a subgraph7 are pooled and rebated to the indexers & delegators depending on the rate set by the indexer. These rebates are also subject to a dispute period and land in the indexer’s wallet several days after the indexing rewards. This gives rise to another revenue cut-off issue since you can’t estimate your query fee rebates as easily as the indexer rewards. They magically land in your wallet several days after the performance obligation they relate to and poof, more revenue!

Accruing indexer rewards but leaving query fee rebates hanging mixes up the cash versus accrual method of bookkeeping, which isn’t ideal. The query fee tends to be de minimis but they’re a nuisance when trying to tie-out revenue.

#2 Token Balance Sheet Completeness

There’s a tornado of moving addresses involved in The Graph, some of which are probably not obvious to the accounting department. For a typical indexer, you have the public operator address (what the delegators point their stake to) and the beneficiary address (where the indexer rewards and query fee rebates land). The beneficiary address is set when the validator is provisioned and can also be used to delegate.8

The address that stumped me, however, was the indexer operator address. This string of characters is a “helper” account that acts on behalf of the indexer to open & close allocations, claim rewards, and manage subgraphs. It’s an account that only holds a few ETH at a time for gas fees, but the indexer does own that address and should be including it on their token balance sheet. Most ETH-based protocols such as Chainlink, The Graph, Livepeer, etc. have these agent addresses where small amounts of ETH are squirreled away. They’re easy to overlook but as your networks balloon, the tiny dollops of ETH start to add up.

In general, it’s also important to make sure your locked stake is on your token balance sheet since your token tracking software (i.e. CoinTracker, Bitwave) is most likely tagging that as an outflow. Whenever you send tokens to a staking contract, that should be categorized as an internal transfer, not a send or a trade.

#3 Token Vesting Schedules

The Graph might love token unlock schedules and their pristine tokenomics, but crypto accountants probably feel otherwise. The total supply of 10 billion GRT tokens have already been minted, but the majority of those tokens were subject to lockups. According to The Graph blog, “Over the next 2 – 5 years, a number of token unlocks will occur” per the following release dates:

As you can see, most of the tokens have been unlocked as of September 2023! Source: The Graph

Parties that received these tokens include early VC backers (i.e. Multicoin Capital, Coinbase Ventures), Edge & Node (the main core dev team behind The Graph), The Graph Foundation, indexers, curators, and more. The GraphTokenLockManager.sol contract is responsible for setting the parameters for these locked tokens and can be easily queried on Etherscan. If you’re one of these early Graph supporters, I’d recommend you find your contract, get the original deposit amount and calculate the unlock dates so you can start recognizing that revenue. A quick breakdown of how to find this information using this example contract is below:

  • Find the transaction on Etherscan (should be the first transaction under the “Erc20 Token Txns” tab). To find the contract associated with your beneficiary address, see this tutorial on The Graph Academy.
  • Click into the transaction hash and select “Click to show more” on the “Overview” tab.
  • Click “Decode Input Data” under the pop up box with the function “createTokenLockWallet().”
  • The following parameters will be displayed:
  • Owner
  • Beneficiary
  • managedAmount
  • startTime
  • endTime
  • periods
  • releaseStartTime
  • vestingCliffTime
  • Revocable
  • The startTime and endTime parameters are displayed in unix time9 and need to be converted into “normal” time for the accountants to make sense of. The managedAmount is your initial amount of locked tokens and periods is the number of periods the vest is spread over. For our example, testnet indexers received 3% of the minted GRT with a one year vesting schedule (periods = 12).
  • You can calculate the unlock dates & amounts yourself or use this handy calculator The Graph Academy put together.

The accounting for vesting contracts can be just as technically hairy. I recommend going through the 5 Step Revenue Recognition process under US GAAP to determine if / how much of the GRT can be recognized upon token lock issuance.  In our example, GRT was received upon mainnet launch for participating in the incentivized testnet. I’ve seen a few different methods of recognition for this type of transaction:

Deferred Revenue

When the token lock contract is created (i.e. 12/17/2020 for the example contract), the revenue can be booked to deferred revenue and reclassed to revenue each period. Initially, the GRT is illiquid and only good for bonding to indexers and earning liquid rewards. The principal amount is stuck in limbo and only available for withdrawal at predefined times. The series of entries is as follows:

Receiving the locked tokens

Debit Digital Assets
Credit Deferred Revenue

Every unlock period (starting with 12/17/2020 in our example)

Debit Deferred Revenue
Credit Testnet Rewards

Note: be careful with pricing in this scenario since you may have use pricing at contract inception instead of the fair market value at unlock date.

Recognizing 100% of Revenue Up Front

A case could be made that the performance obligation for testnet work is satisfied upon mainnet launch, so 100% of the GRT can be recognized when it’s received in the lock. In this scenario, the journal entry would read:

Debit Digital Assets
Credit Testnet Rewards

In the notes to your financial statements, you would need to disclose the nature of the lock and the remaining duration.

Depending on your role within The Graph ecosystem, if you were an early backer, there’s a good chance you have tokens that are ripening over time. The same accounting concept applies to any other network that rewards early participants with the native token subject to an unlock period.

The Graph Accounting Enigma

The Graph is hands down one of the most innovative and necessary players in the web3 ecosystem. It started out with breaking down data on Ethereum and has expanded to NEAR, Celo, Avalanche, and Moonbeam. It’s an incredibly powerful tool for both developers and anyone looking to get accurate and timely data. The accounting is a meadow of briers but the data is all there, hidden in stacks of Etherscan pages. Crypto accountants will have a lovely puzzle on their hands. 🧩


1. The self-stake is the number of native tokens required to spin up an indexer (aka validator). For The Graph, the minimum amount is 100,000 GRT, with the delegator ratio set at 16x self-bond. For example, if you bond 4,000,000 GRT, you can accept outside delegations of up to 64,000,000 GRT. The self-stake may be slashed for malicious or incorrect behavior.
2. The “curator” plays an unusual role in The Graph - they signal what subgraphs should be indexed and earn a share of any query fees generated. The earlier a curator signals on a high-quality subgraph, the more rewards they earn (based on Bancor’s implementation of a bonding curve).
3. Allocations become stale after 28 days since they stops earning query fees (the indexer’s delegators can also force close those allocations). Responsive indexers should re-allocate before they become stale.
4. The proof of indexing (POI) is required for an allocation to be closed. It serves as a mathematical proof that the indexer did its job correctly.
5. There are a few limitations to this: an allocation cannot be opened and closed within the same epoch, and it is strongly discouraged to close after allocations are older than 28 epochs (the indexer loses rewards).
6. Graphscan displays two different types of fee cuts, effective and stated. The effective rate is how much of the rewards the indexer is actually taking relative to how much it would’ve collected at the stated rate. This Graph Academy article goes in depth on what this means. Overall, to get your total indexer revenue, you need to multiply total rewards by the effective (not stated fee) since that’s a more accurate view of what the indexer is taking home.
7. Query fees are generated whenever someone queries a piece of data from a particular subgraph i.e. What were the total delegations on Audius protocol on December 31, 2021?
8. See Prime-2 indexer here.
9. Per Wikipedia, “Unix time is a system for describing a point in time. It is the number of seconds that have elapsed since the Unix epoch, excluding leap seconds. The Unix epoch is 00:00:00 UTC on 1 January 1970.”
Mackenzie Patel

Related Content

BACK TO BLOGBACK TO BLOG