Skip to content

Incorrect indexerQueryFees and delegationPoolQueryFees calculation #328

@warfollowsme

Description

@warfollowsme

Description

The handleQueryFeesCollected handler in src/mappings/subgraphService.ts incorrectly computes the split between indexer query fees and delegation pool query fees. This leads to inflated/deflated values for indexerQueryFees, delegatorQueryFees, and all downstream aggregations (Indexer, Allocation, Epoch, SubgraphDeployment, GraphNetwork, PaymentSource entities).

Current Code

    let delegationPoolQueryFees =
        provision.delegatedTokens == BigInt.fromI32(0)
            ? BigInt.fromI32(0)
            : event.params.tokensCollected
                .times(provision.queryFeeCut)
                .div(BigInt.fromI32(1000000))
    let indexerQueryFees = event.params.tokensCollected.minus(delegationPoolQueryFees)

Problems

  1. provision.queryFeeCut represents the indexer's cut, not the delegation pool's cut

queryFeeCut is share that the indexer takes for themselves. The current code multiplies tokensCollected by queryFeeCut and assigns the result to delegationPoolQueryFees — this is inverted. The value computed is actually the indexer's share, not the delegation pool's share. More here: #325

  1. The fee split does not account for protocol and curators deductions

According to the smartcontract logic, the distribution of collected query fees follows this order:

  • Protocol fee (burned) — a percentage (protocolFeePercentage) is taken from the total collected amount first.
  • Curator fee — a percentage (curationPercentage) is taken from the remaining amount after the protocol fee.
  • Indexer fee — the indexer takes their share (queryFeeCut PPM) from what remains after protocol and curator deductions.
  • Delegation pool — the remainder (if any delegated tokens exist) goes to the delegation pool.
    The current code skips steps 1 and 2 entirely, applying queryFeeCut directly to the raw tokensCollected value. This results in an incorrect base amount for the fee split calculation.

Proposed Fix

// Step 1: Calculate protocol fee (burned)
let tokensProtocol = event.params.tokensCollected
    .times(graphNetwork.protocolFeePercentage)
    .div(BigInt.fromI32(1000000))

// Step 2: Calculate curator fee from remaining amount
let tokensCurators = event.params.tokensCollected
    .minus(tokensProtocol)
    .times(graphNetwork.curationPercentage)
    .div(BigInt.fromI32(1000000))

// Step 3: Calculate indexer's cut from the remainder (after protocol + curator fees)
let indexerQueryFees = event.params.tokensCollected
    .minus(tokensProtocol)
    .minus(tokensCurators) //or just .minus(event.params.tokensCurators) and prev part is unnecessary
    .times(provision.queryFeeCut)
    .div(BigInt.fromI32(1000000))

// Step 4: Delegation pool receives whatever is left
let delegationPoolQueryFees =
    provision.delegatedTokens == BigInt.fromI32(0)
        ? BigInt.fromI32(0)
        : event.params.tokensCollected
            .minus(tokensProtocol)
            .minus(tokensCurators)
            .minus(indexerQueryFees)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions