Reward-Flywheel Initialization and Checkpoint Coherence
-
Name: reward-flywheel initialization and checkpoint coherence
-
Category: rewards reference / migration checklist / checkpoint-state coherence note / initialization-boundary companion
-
Summary: Healthy reward flywheels do not let
market initialized,user checkpoint initialized,baseline accrual starts here, andthis payout may transfer real tokensbecome four separate stories. A cumulative-index system can safely use nonzero baselines such as1e36, lazy first-touch checkpointing, or staged governance migrations, but only if those surfaces still behave like one security object. If market state saysinitialized, user state still says0, and payout logic trusts the resulting delta as earned reward, the protocol has already turned initialization semantics into a mint rail. This note exists to preserve the positive-design target behind Compound Proposal 62: reward-index rollout, checkpoint normalization, and transfer authorization should stay coherent across upgrades, dormant accounts, and exact-boundary states. -
Why this note exists:
- Reward-index initialization failure already preserves the negative family clearly: a zero-sentinel / first-touch boundary manufactures bogus reward accrual.
- What deserves its own positive-design note is the healthier control surface beneath that exploit family: how a reward system should represent initialization explicitly, migrate live users, constrain lazy checkpointing, and keep transfer rails skeptical when accounting state enters a freshly upgraded boundary.
- The analytical win is to ask
what exact state machine says this market and this user are now aligned on the same reward baseline?before arguing about whether the immediate bug was>versus>=, a partial migration, or a missing one-off normalization step.
The six joints a healthy reward flywheel should keep fused
1. Market initialization and user initialization should be separate facts, not overloaded numbers
- A reward flywheel should be able to answer two distinct questions cleanly:
is this market side initialized?andhas this user checkpoint been normalized to that market side yet? - Numeric values like
0,initialIndex, and> initialIndexcan still exist, but they should not be the only way the system infers lifecycle state. - Once sentinel values carry both accounting magnitude and lifecycle meaning, equality boundaries stop being arithmetic trivia and become access-control-like security decisions.
2. Baseline accrual should be explicit
- If a market initializes at a nonzero baseline such as
compInitialIndex = 1e36, then the system must say exactly what that baseline means economically:initialized but no accrual yet,accrual starts here, orhistorical emissions already embedded. - User checkpoints should be normalized to that same baseline before any delta is interpreted as earned reward.
- The important property is not
the market has a nonzero index. It ismarket and user state agree on whether any delta before this point is real.
3. Migrations should normalize live state eagerly when practical
- Governance upgrades, side splits, and flywheel refactors should prefer explicit normalization of live user checkpoints during migration when gas and complexity allow.
- Lazy first-touch initialization is only safe when it is tested and proved equivalent to eager normalization for every pre-existing supplier and borrower cohort.
- A migration that eagerly changes market state but leaves user-state meaning to future interactions is choosing to keep a live inconsistency window open.
4. First-touch logic should settle from one coherent state version
- Claim, mint, borrow, repay, transfer, or any other flywheel-touch path should either normalize stale user state first or refuse to compute reward deltas until normalization has happened.
- The key rule is simple: the state version used to update the user checkpoint must be the same state version used to compute any immediately claimable delta.
- If the code updates storage to the new checkpoint but computes the delta from the old local value, the protocol is already trusting split-brain accounting.
5. Transfer rails should distrust impossible first-touch windfalls
- Reward accrual entries are not sacred just because upstream accounting produced them.
- A healthy payout rail can still ask whether one user is suddenly claiming more than plausible emissions, more than expected distributor inventory, or more than any first-touch interaction should ever authorize.
- This is not a replacement for correct accounting. It is the fail-closed layer that keeps one migration bug from becoming an immediate treasury outflow.
6. Rollback and cleanup paths should already exist before the migration ships
- Reward migrations should launch with a known response plan: pause scope, claim restrictions, affected-account discovery, bad-accrual adjustment, and receivable / clawback bookkeeping if needed.
- The right time to design those paths is before the upgrade, not after a live flywheel disagreement has already printed impossible balances.
- A reward system that can mint accounting fiction should also have a bounded way to quarantine and unwind that fiction.
Three initialization facts reward reviewers should not collapse
1. The market side has entered a live baseline state
Market initializedis only the first promotion: the protocol has published one baseline index, one market-side emission frame, or one borrower / supplier-side readiness state.- That can still be true even while many pre-existing users remain un-normalized to that same frame.
2. This specific user has been normalized to that same baseline
- A dormant supplier, borrower, or delegate is not economically ready just because the market-side index now exists.
- The protocol still needs one explicit transition that says
this user's checkpoint now means the same thing as the market's initialized baseline.
3. This path may already monetize the resulting delta
- Even after market readiness and user normalization are understood, there is one more security decision: can this exact claim, supply, borrow, transfer, or helper path already turn the computed delta into real token outflow?
- Compound Proposal 62 was expensive because those three answers drifted apart: market-side initialization happened, user normalization lagged, and payout logic still treated the disagreement as immediately payable reward.
What sound design looks like
1. Explicit lifecycle state instead of folklore about sentinels
- Market-side readiness and user-side checkpoint readiness should be represented directly enough that reviewers can reason about them without mentally decoding magic numbers.
- If numeric sentinels remain, code and tests should still treat them as an implementation detail over a clearer state model.
- The clean target is not merely
index exists; it ismarket-side baseline publication, user normalization, and payout authority all remain separate questions until the protocol has deliberately fused them again.
2. One normalization story across claim, supply, borrow, and transfer surfaces
- Every path that can realize or advance reward state should share the same internal normalization primitive.
- If
claimComp(), supply-side distribution, borrower-side distribution, or token-transfer hooks each interpret zero checkpoints slightly differently, drift is not hypothetical. - The design target is one answer to
what baseline should this user now be measured from?
3. Equality-boundary tests as first-class migration coverage
- Test suites should intentionally hit
0,initialIndex, andinitialIndex + 1style states for both market and user checkpoints. - Fork simulations should include dormant suppliers, dormant borrowers, newly activated market sides, and accounts that have not interacted since before the migration.
- In this family, the equality case is often the exploit, so equality deserves production-grade test coverage.
4. Payout plausibility bounds at the treasury edge
- The reward distributor should not act as though every accrual entry is equally trustworthy.
- Per-market claim pauses, affected-market allowlists, per-account anomaly guards, or explicit
receivablebookkeeping can keep a flywheel bug from immediately emptying live inventory. - The design goal is not to silently cap legitimate rewards. It is to ensure impossible first-touch accrual fails closed long enough for humans or governance to respond.
- Healthy payout rails should behave as though
market looks initializedis still not the same thing asthis user's first-touch delta is treasury-valid right now.
5. Migration bundles that include observability
- A good flywheel rollout ships with monitoring for first-touch anomalies, impossible per-block accrual, dormant-account windfalls, and sudden divergence between accrued rewards and intended emission budget.
- Upgrades should not merely change code; they should also arm the detection needed to prove the new state machine is behaving as designed.
Negative exemplar cluster: what underdesigned checkpoint coherence looks like
- Compound V2 Proposal 62 is the canonical case: market reward indices were initialized to
1e36, some user checkpoints remained0, and first-touch distribution logic treated the exact1e36equality boundary as if it were real historical accrual. - The reusable lesson is not merely
fix the comparison operator. It ismarket initialization, user checkpoint normalization, and transfer authorization must all agree on the same baseline state machine before any live treasury asset moves. - The adjacent cousin is denominator-collapse reward amplification, where the coherence failure is not the zero-sentinel boundary but a later disagreement between global accumulator truth and user debt truth.
Red flags that usually mean a reward migration is relying on folklore
Zero means uninitialized everywhereWe'll lazily normalize users the next time they interactThe baseline index is harmless because no rewards have accrued yetIf claim accounting is wrong, distributor inventory will limit the damageWe upgraded the market state, so user checkpoints will sort themselves outWe tested fresh accounts; old dormant accounts should behave the sameThe patch is only changing one comparison, so extensive migration simulation is unnecessary
Design questions worth asking first
- What exact state object says this market side is initialized, and what separate state object says this specific user is aligned to that baseline?
- If a market uses a nonzero initial index, what economic meaning does that baseline carry, and where is that meaning documented in code and tests?
- Which code path normalizes stale user checkpoints, and is that same logic reused across supplier, borrower, and claim surfaces?
- Can a user move from
checkpoint = 0tocheckpoint = initialIndexwhile still realizing a positive reward delta in the same call? - Were dormant pre-upgrade accounts tested on forked live state, or only newly created accounts in unit tests?
- What anomaly guard stops one impossible first-touch claim from draining live reward inventory before governance can react?
- If a cleanup proposal becomes necessary, what bookkeeping records over-accrued but already-transferred rewards without corrupting future honest accrual?
- Which logs, dashboards, or alerts would reveal that post-upgrade reward accrual exceeds plausible emissions?
Failure-prevention checklist
- Represent market initialization and user-checkpoint initialization explicitly enough that reviewers do not have to infer lifecycle state entirely from sentinel numbers.
- Force reviews and tests to answer three separate questions:
has the market side published a live baseline?,has this user been normalized to that baseline?, andmay this path already turn the delta into payout? - When a nonzero baseline index is introduced, test the exact equality boundary on every side of the flywheel: supplier, borrower, claim, and any helper that advances checkpoints.
- Prefer eager checkpoint normalization during migrations; when lazy normalization remains, prove its equivalence against real pre-upgrade account state with forked simulations.
- Reuse one internal normalization primitive across all reward-touching paths so market-side and user-side baseline semantics cannot drift by surface.
- Ensure delta computation and checkpoint update read from one coherent state version. Never let a path update stored checkpoint state while calculating claimable reward from a stale local sentinel.
- Add payout-rail guards or market-scoped quarantine so impossible first-touch accrual cannot automatically become an immediate treasury outflow.
- Ship monitoring for post-upgrade anomalies: single-touch windfalls, accrued-vs-emission divergence, affected dormant accounts, and sudden claims from newly activated market sides.
- Predefine cleanup mechanics for bad accruals, including how over-claims, receivables, and restored honest accrual will be recorded if rollback is incomplete.
- Treat governance flywheel upgrades as security-critical migrations requiring fork tests, scenario tests, and explicit reviewer signoff on initialization semantics.
Audit prompts
- What exact state object says this market side is initialized, and what separate state object says this user’s checkpoint has been normalized to that same baseline?
- Where, exactly, does the system decide that
market baseline existshas becomethis user is aligned to itrather than merelythis user has now touched the code path? - Can any path move a user from
checkpoint = 0tocheckpoint = initialIndexwhile still computing a positive reward delta from the stale pre-normalized view? - Do supplier, borrower, claim, transfer, and helper surfaces all call the same normalization primitive, or are there multiple subtly different first-touch rules?
- Which equality boundaries were exercised on forked pre-upgrade state:
0,initialIndex,initialIndex - 1, andinitialIndex + 1for both market and user checkpoints? - If migration leaves lazy normalization in place, what evidence proves it is equivalent to eager migration for dormant live accounts rather than only for fresh test accounts?
- What treasury-edge control stops one impossible first-touch accrual from becoming an immediate distributor outflow before humans can react?
- Can a partially normalized user or market state survive across revert, retry, or cross-surface interactions long enough for sibling paths to read a different lifecycle meaning?
- What telemetry would reveal that reward accrual is outrunning intended emissions: dormant-account windfalls, newly activated side spikes, or claim volume concentrated in first-touch interactions?
- If bad accrual already transfers tokens, what bookkeeping records the overpayment without corrupting future honest accrual for the same users and markets?
- During review, who explicitly signs off on the initialization state machine itself rather than only on the arithmetic diff?
Lessons that should already be standard
- Sentinel values are part of the security model once payout logic infers lifecycle state from them.
- Reward migrations fail most expensively at equality boundaries and on dormant accounts, so those are the cases that deserve the most test realism.
Market initialized,user normalized, andthis payout is now validare three different promotions. Treating them as one vague meaning ofinitializedis how bookkeeping turns into a mint rail.- Lazy normalization is a security choice, not just a gas optimization. It deliberately keeps a live inconsistency window open until proven equivalent to eager migration.
- A reward distributor should distrust impossible first-touch windfalls even if upstream accounting produced them; treasury outflow is the wrong place to be maximally trusting.
We only changed one comparisonis not a small change when that comparison decides whether historic emissions are real or fictional.- Governance upgrades to reward state are balance-sheet events. They deserve fork simulations, anomaly monitoring, and rollback thinking before activation, not after.
- One coherent normalization story across every reward-touching surface is healthier than several almost-equivalent first-touch rules.
- If market initialization, user initialization, and payout authorization are allowed to drift into separate meanings of
initialized, the protocol has already built a mint rail out of bookkeeping.
How to use this note with the exploit corpus
- Start here when the sharper design question is
how should a cumulative reward-index system keep market initialization, user checkpoint initialization, and payout authorization on the same state machine? - Pair with reward-index-initialization-failure for the negative exploit family where a first-touch boundary manufactures reward accrual from inconsistent sentinel semantics.
- Pair with reward-entitlement-identity-and-batch-canonicalization when the sharper question is how batch claim helpers should authenticate and consume canonical reward rights after the flywheel has already computed reward state.
- Pair with denominator-collapse reward amplification when the flywheel’s disagreement shows up not at initialization but in later accumulator-versus-user-debt settlement.
- Pair with sync-harvest-and-cache-write-authority-discipline when the sharper question is who gets to publish pending reward state into canon, especially if the exploit needs an attacker-timed
harvest,checkpoint, orsync. - Pair with exit-right-consumed-state-binding when downstream claim logic must ensure that once reward has been realized, sibling paths cannot still treat the same entitlement as fresh.
Internal linkages
- Canonical negative family: reward-index-initialization-failure.
- Canonical incident exemplar: Compound V2 Proposal 62.
- Reward-entitlement companion: reward-entitlement-identity-and-batch-canonicalization.
- Reward-debt settlement companion: reward-debt-desynchronization-denominator-collapse-reward-amplification.
- Publication-authority companion: sync-harvest-and-cache-write-authority-discipline.
- Consumed-state companion: exit-right-consumed-state-binding.
Control surface
-
The decisive control surface is the boundary between
this market side has published a live baseline,this user's checkpoint has been aligned to that baseline, andthis accrued reward may now transfer real tokens. -
Healthy systems keep those answers distinct during rollout and then deliberately fuse them through one normalization story across governance rollouts, dormant accounts, and exact-boundary states.
-
Unsafe systems let market-side migration, user-side lazy initialization, and payout authorization each improvise their own meaning of
initialized, then pay out the disagreement. -
Sources:
-
Last reviewed: 2026-07-27 UTC