Skip to content

Sync committee rewards API returns validator balance instead of reward delta #8718

@moshe-blox

Description

@moshe-blox

Description

We believe there may be a bug in the /eth/v1/beacon/rewards/sync_committee/{block_id} API where it returns the validator's full balance instead of the reward/penalty delta.

We could be wrong in our analysis, so please correct us if we're misunderstanding the expected behavior.

Observed Behavior

When calling the sync committee rewards API on Lodestar v1.38.0, we get values like:

  • "reward": "32675030525" (~32.6 ETH in gwei)

When calling the same API on Teku or Lighthouse for the same slot/validator:

  • "reward": "25038" (~25,000 gwei)

The Lodestar value closely matches the validator's balance, while Teku/Lighthouse return what appears to be the actual sync committee reward delta.

Expected Behavior (based on spec)

From the Beacon API spec, the SyncCommitteeRewards schema shows:

reward:
  example: "2000"
  description: "sync committee reward in gwei for the validator"

The example value of 2000 gwei suggests the field should contain the small reward delta, not the full validator balance.

Evidence

We tested against multiple beacon nodes behind a load balancer on Hoodi testnet:

Client Version Reward Value Interpretation
Lodestar v1.38.0 ~32,000,000,000 Appears to be validator balance
Teku v25.12.0 ~25,000 Appears to be reward delta
Lighthouse v8.0.1 ~25,000 Appears to be reward delta

We also compared the Lodestar "reward" value to the validator's actual balance and they match almost exactly (within a few thousand gwei).

Suspected Code Location

In packages/beacon-node/src/chain/rewards/syncCommitteeRewards.ts, the function appears to:

  1. Initialize a map with validator balances
  2. Add/subtract syncParticipantReward
  3. Return the resulting balance value

The final line returns v.val which is the balance after adjustment, rather than the delta:

const rewards = Array.from(balances, ([validatorIndex, v]) => ({validatorIndex, reward: v.val}));

Compare to Lighthouse which calculates new_balance - initial_balance to get the delta.

Impact

This caused incorrect APR calculations in our monitoring system when requests were routed to Lodestar nodes.

Environment

  • Lodestar version: v1.38.0
  • Network: Hoodi testnet
  • Also checked latest unstable branch - same behavior

Again, we may be misunderstanding something about how this API is supposed to work. Happy to provide more details or test cases if helpful.

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