Skip to content

feat: cumulative factors and delegator shares for O(1) stake computation#217

Open
adamsoffer wants to merge 1 commit intolivepeer:mainfrom
adamsoffer:claude/magical-tereshkova
Open

feat: cumulative factors and delegator shares for O(1) stake computation#217
adamsoffer wants to merge 1 commit intolivepeer:mainfrom
adamsoffer:claude/magical-tereshkova

Conversation

@adamsoffer
Copy link
Contributor

@adamsoffer adamsoffer commented Mar 8, 2026

Problem

The subgraph has no way to compute a delegator's actual total stake. The bondedAmount field only reflects the value at the time of the last claim and does not include rewards earned since then. To get a delegator's current stake, clients must call the contract's pendingStake() method directly — and for historical stake at a past round, there is no solution at all.

This also means there's no way to build time-series charts of delegator stake, show per-round reward breakdowns, or compute orchestrator yield — all of which require knowing stake values across rounds.

Summary

  • Store cumulativeRewardFactor and cumulativeFeeFactor on the Pool entity, matching on-chain PreciseMathUtils (27-decimal fixed-point)
  • Propagate cumulative factors forward each round during pool creation so every pool has valid values (no gaps for missed reward() calls)
  • Add shares field to Delegator (bondedAmount * 10^27 / crf[lastClaimRound]) — invariant across claims, only changes on bond/unbond/rebond
  • Add DelegatorSnapshot entity capturing delegator state at each bond/unbond/rebond for time-series chart support
  • Compute cumulative fee factor in WinningTicketRedeemed handler using previous round's CRF (matching contract behavior)

What this unlocks

Current pending stake without contract calls — A delegator's up-to-date total stake (equivalent to pendingStake() on-chain) can now be computed entirely from the subgraph: query the delegator's shares and the current round's Pool.cumulativeRewardFactor for their orchestrator, then compute shares * crf / 10^27. No contract call needed.

Historical stake at any past round — Something previously impossible. Query the delegator's shares (or the relevant DelegatorSnapshot) and the Pool.cumulativeRewardFactor for that round, then compute shares * crf[round] / 10^27.

Per-round reward and fee breakdowns — Rewards earned in a specific round can be derived by comparing cumulative factors between consecutive rounds: rewards = shares * (crf[round] - crf[round-1]) / 10^27. Same pattern applies to fees using cumulativeFeeFactor.

Time-series charts of delegator stake — The shares approach combined with DelegatorSnapshot entities makes it straightforward to build a chart showing a delegator's total stake over time. Between snapshots, shares are constant, so stake at any round is just shares * crf[round] / 10^27. When a bond/unbond/rebond occurs, a new snapshot captures the updated shares value to use going forward.

Orchestrator pool analytics — Cumulative factors stored per-pool per-round enable computing total rewards distributed, effective yield, and fee revenue for any orchestrator over any time range without replaying events.

All changes are additive — no breaking changes to existing queries.

Test plan

  • Run npx graph codegen && npx graph build — verified locally
  • Deploy to a staging subgraph and verify cumulative factors match on-chain values
  • Verify delegator shares remain constant across claim events
  • Verify shares * crf[round] / 10^27 matches actual bonded amounts
  • Verify pending stake computed from subgraph matches contract pendingStake() return value
  • Verify DelegatorSnapshot entities are created on bond/unbond/rebond but not on claim

🤖 Generated with Claude Code

…cient historical stake computation

Store cumulativeRewardFactor and cumulativeFeeFactor on Pool entity
(matching on-chain PreciseMathUtils), propagate them forward each round,
and introduce a shares field on Delegator that enables O(1) stake lookups
via `stake = shares * crf[round] / 10^27`. DelegatorSnapshot entities
capture state at bond/unbond/rebond events for time-series chart support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@adamsoffer adamsoffer requested a review from rickstaa as a code owner March 8, 2026 20:54
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