Reward-Recognition, Presentation, and Collateral-Admission Separation

  • Name: reward-recognition, presentation, and collateral-admission separation
  • Category: vault reference / reward-accounting checklist / share-price timing boundary / downstream-solvency reference
  • Summary: Some vault and wrapper systems fail not because their reward source is fake, but because they let one still-unsettled or attacker-timed reward state collapse three different promotions into one number: what future or pending rewards exist, what the protocol is willing to publish as current user balances or share price, and what outside lending, liquidation, or recursive-borrow systems may treat as money-good debt authority right now. Healthy systems keep those phases separate. Pending strategy gains, syncable rewards, donated yield-side inventory, cached NAV, and rebasing presentation should not all become same-block redemption truth, borrow power, liquidation authority, or loopable collateral authority.
  • Why this note exists:
    • Donation / share-price manipulation notes explain how an attacker prints a higher rate. This note exists for the narrower design question that keeps recurring in GoGoPool, Zunami, Raft, Wise, and ResupplyFi: when should a rate count as user-visible value at all?
    • sync-harvest-and-cache-write-authority-discipline is the still narrower authority-side companion when the sharper follow-up is not just when should that value count?, but who was allowed to crystallize it into canonical share truth, with what effect bounds, and for which downstream consumers?
    • Reward-bearing wrappers often compress future rewards, current share price, presentation-layer balances, and downstream collateral truth into one moving scalar. That collapse is the control-surface mistake.
    • The analytical win is to separate a strategy or reward source may eventually owe more value from the token contract, vault, or sibling lending market may already spend, borrow, liquidate, or snapshot that value.

The four states a healthy design should keep distinct

  1. Reward provenance

    • The system should know what exact event produced the extra value: harvested strategy proceeds, protocol rewards, validator rewards, explicit donations, debt repayment residue, or another balance-side change.
    • Assets went up is not enough if the same increase could come from attacker-timed donation or another path that should not immediately enrich holders.
    • This is where balance-delta-provenance-failure and donation-share-price-manipulation often begin.
  2. Recognition state

    • The system should know whether those rewards are merely observed, internally staged, fully settled, or already merged into canonical per-share economics.
    • A public syncRewards() or cache update should not act like a magic ceremony that turns any balance-side increase into fully distributable value with no further distrust boundary.
    • Recognition should usually be a bounded state transition, not an ambient consequence of whoever called the right helper at the right time.
  3. Presentation state

    • balanceOf, rebases, cached NAV, receipt-token exchange rate, or UI-facing asset-per-share math should not automatically consume the newest recognizable rate just because it exists.
    • Presentation may need smoothing, delay, haircut, or explicit exclusion of attacker-triggerable components before it becomes user-spendable or allowance-relevant truth.
    • This is the seam exposed most clearly by Zunami and Raft Finance.
  4. Collateral-admission state

    • Even if vault-local accounting and user-facing presentation are coherent enough for the wrapper itself, outside lending markets and liquidators should not instantly treat the freshest possible repricing as money-good collateral.
    • Collateral truth often needs a stronger boundary than presentation truth: separate oracle adapters, caps, delays, haircut windows, or recursive-borrow suppression.
    • This is where collateral-admission-lag-and-borrow-side-quarantine and recursive-borrow-suppression-for-fresh-collateral become the narrower downstream companions.

Three promotions reviewers should not collapse

  1. Pending or observed value exists

    • A strategy, validator set, donation path, or thin-market wrapper may have produced a value increase that is economically real in some narrow sense.
    • That still only answers did something happen that might later enrich holders?
  2. The protocol published that value as accounting truth

    • A sync, harvest, index update, cache write, or rebase may move that pending value into canonical share price, balanceOf, assetsPerShare, or another user-visible wrapper truth.
    • That answers a stronger question: did the protocol socialize the value into holder accounting right now?
  3. Outside systems honored that accounting truth as debt authority

    • A lending adapter, liquidation path, recursive-borrow rail, or reserve-backed redemption path may then treat the freshly published wrapper mark as immediate money-good collateral.
    • That is a third and still stronger claim: may other balance sheets spend, lend, or liquidate against this mark already?

Most incidents in this cluster do not start and end at one step. The exploit is usually the collapse between them.

What sound design looks like

1. Reward staging before share-price recognition

  • Newly observed rewards should first land in an explicit staging state rather than instantly rewriting canonical totalAssets or assetsPerShare.
  • If strategy rewards, validator rewards, or donated inventory are not yet safe to treat as holder-owned principal, keep them in a bucket that cannot directly drive mint, redeem, balanceOf, or collateral calculations.
  • The key design question is not did value appear? but what exact state transition proves that value is now safe to socialize across all holders and integrations?

2. Sync paths should be bounded, not rate-authoring superpowers

  • Public or weakly controlled sync, harvest, checkpoint, updateIndex, or cache-write functions should not let the caller choose the exact instant when manipulable external state becomes canonical share truth.
  • If synchronization is unavoidable, it should come with bounded inputs, anti-sandwich assumptions, or delayed effectiveness.
  • sync-harvest-and-cache-write-authority-discipline is the narrower companion when the sharper design question is what publication rights, activation delays, and per-call effect caps should have wrapped those helpers once they were capable of rewriting holder or collateral truth.
  • GoGoPool is the clean reminder that reward-sync timing alone can be enough to turn the next depositor into the payout rail.

3. Presentation math should lag fragile repricing

  • Rebase math, cached balances, and convertToAssets-style helpers should not become same-block consumers of attacker-timed reward or donation state.
  • If the protocol cannot prove the new rate is robust, presentation should lag or discount it rather than making it immediately spendable or allowance-relevant.
  • Publishing wrapper-local accounting truth is already a strong promotion. Treat it as a distinct ceremony from raw reward observation, not as a harmless mirror of whatever value is currently most flattering.
  • Zunami and Raft preserve the two main cousins here: cached NAV that expands user balances and rebasing/index math that makes printed collateral look natively real.

4. Collateral truth should be stricter than wrapper-local truth

  • A wrapper rate being locally valid enough for internal accounting does not mean it is safe as lending collateral right now.
  • Freshly repriced wrappers should often face delayed admission, tighter caps, or borrow-side restrictions even after the wrapper itself considers the new rate canonical.
  • Published accounting truth is still not automatic debt authority. The lending side should earn its own slower, narrower promotion instead of inheriting the wrapper’s freshest mark by default.
  • ResupplyFi is the sharp reminder that once a lending layer accepts a fresh printed wrapper mark too literally, downstream math can collapse into impossible states like zero-cost debt.

5. Published wrapper truth is still not loopable debt authority

  • Even after a wrapper publishes a mark as canonical for its own holders, same-thesis leverage rails should usually stay narrower: recursive borrow against the wrapper, wrapper-versus-underlying loops, same-block self-liquidation paths, and reserve-backed redemption surfaces should not automatically inherit that freshest mark.
  • The important separation is the wrapper may now describe holder economics this way versus another balance sheet may now lever, refinance, or liquidate against that exact mark without delay.
  • Healthy designs keep loop-enabling rails on a later, stricter gate than wrapper-local accounting. Delayed collateral admission, recursive-borrow suppression, exposure caps, and self-liquidation friction belong to this boundary.
  • Wise Lending and ResupplyFi are the clean reminders that even a locally truthful fresh wrapper rate can still be too attacker-shaped, too thin, or too early to support same-thesis debt creation.

6. Reward recognition and collateral admission should not share one trigger

  • The function that socializes new value across holders should usually not be the same function that grants immediate cross-module borrowing or liquidation authority.
  • If one sync step both updates holder economics and unlocks external collateral capacity, the protocol has collapsed two trust boundaries into one attacker-timed edge.

Strong incident cluster for this note

  • GoGoPool ggAVAX — reward-sync timing plus an unseeded opening state turned future rewards into immediate next-depositor overcharging.
  • Zunami — strategy-side donation plus thin-market repricing became cached NAV, then token-balance expansion.
  • Raft Finance — donation-sensitive collateral index math turned presentation-layer balanceOf() into borrowable collateral truth.
  • Wise Lending — iterative stealth donations show that even without one obvious syncRewards() button, reward-like exchange-rate growth can still be attacker-authored and then admitted as solvency truth too early.
  • ResupplyFi — a freshly accepted wrapper mark crossed straight into downstream borrow math without a nonzero sanity boundary.

Design questions worth asking first

  • What exact events are allowed to increase canonical holder-owned value, and which merely increase raw or pending inventory?
  • Does the system have an explicit observed but not yet socialized reward state?
  • Can any public caller decide when pending rewards become canonical share price or cached NAV?
  • Which functions let a freshly updated rate affect balanceOf, redemption, liquidation, or borrow power in the same block?
  • Are presentation-layer balances and collateral-layer valuations driven by the same update trigger?
  • If a rate is attacker-timed but locally truthful, what keeps downstream lending logic from honoring it immediately?

Red flags

  • syncRewards() or harvest() is treated as harmless bookkeeping even though it rewrites user-visible balances or collateral value.
  • The same fresh rate drives wrapper-local accounting, rebasing presentation, and lending collateral with no separate distrust boundary.
  • Donated or strategy-side inventory becomes share-price truth merely because a helper copied balanceOf into storage.
  • A cache added for gas or UX can be written at attacker-chosen times and later feeds redemption, balanceOf, or collateral math.
  • A wrapper with volatile or manipulable strategy-side value is admitted as collateral on the same timing boundary used for reward recognition.

Failure-prevention checklist

  • Keep observed reward, recognized share value, presentation-layer balance, and collateral-admissible value as separate explicit states in code and reviews; do not let one fresh rate silently answer all four questions.
  • Route newly arrived rewards, donations, strategy proceeds, fee residue, validator accrual, and other balance-side gains through a staging bucket before they can touch totalAssets, assetsPerShare, rebases, or collateral adapters.
  • Decide explicitly which transition socializes pending value into holder economics and which stronger transition, if any, lets downstream lending systems honor it as money-good collateral.
  • Keep wrapper-local presentation freshness looser than collateral freshness. If a rate can be locally useful before it is robust, give lending adapters their own delay, cap, haircut, or quarantine rather than inheriting the freshest wrapper mark.
  • Keep recursive-borrow, self-liquidation, wrapper-versus-underlying loop, and other same-thesis leverage rails on an even stricter gate than ordinary wrapper-local presentation. Published now is still not loopable debt authority now.
  • Refuse same-block collapse from reward observation to borrow power. If one call can observe, recognize, present, and collateralize the same repricing event, the design has already fused too many trust boundaries.
  • Require an explicit second gate between wrapper-local accounting truth and downstream debt authority, even when the wrapper has already accepted the rate as canonical for its own holders.
  • Treat rebasing balanceOf, cached NAV, convertToAssets, exchange-rate reads, and collateral-facing oracle adapters as different consumers with different distrust needs, even when they derive from one underlying economic story.
  • Require reward provenance before socialization. A raw balance increase should not become holder-owned or collateral-relevant merely because it is economically real; the protocol still has to prove what produced it and whether that source is entitled to socialize across all holders.
  • Stress-test the low-liquidity and low-supply edge cases where pending or attacker-timed value moves the rate most violently; many timing-separation bugs only become visible when thin markets, dust supply, or concentrated reward arrival make one update dominate the denominator.
  • Add production monitoring for state transitions that should be rare: large same-block jumps from staged value to presentation value, rebasing balance expansion after externally timed donations, wrapper marks that change shortly before borrowing surges, or collateral adapters consuming a just-updated wrapper price without delay.
  • Make rollback and containment part of the design: if pending value was recognized too early, the protocol should know how to freeze collateral use, haircut the adapter, or revert to the last trusted mark without also breaking ordinary user accounting.

Audit prompts

  • What exact state machine governs the path from reward observed to holder economics updated to presentation changed to collateral admitted, and where is each transition enforced?
  • Which code path first publishes a rate as wrapper-local accounting truth, and which separate code path — if any — later authorizes lending, liquidation, or recursive-borrow systems to honor that same rate as debt authority?
  • Which events can increase raw inventory without yet increasing holder-owned value, and where does the code preserve that distinction instead of collapsing both into totalAssets or equivalent rate math?
  • Can any public caller choose when pending rewards, donated assets, strategy gains, or thin-market marks become visible through balanceOf, rebases, cached NAV, convertToAssets, or collateral adapters?
  • Are presentation-layer consumers and collateral-layer consumers wired to the same freshest mark, or does collateral admission preserve its own lag, haircut, or borrow-side quarantine?
  • If the wrapper’s local accounting is valid but still fragile, what stops a sibling lending market from treating that fresh repricing as immediate money-good collateral?
  • After the wrapper publishes a fresh mark, which exact rails still remain closed: recursive borrow, wrapper-versus-underlying loops, self-liquidation, reserve-backed redemption, or thin-market leverage paths? Where is that narrower gate enforced?
  • Which code paths let a newly recognized rate affect minting, redemption, liquidation, borrow capacity, or recursive leverage in the same block?
  • What provenance proof distinguishes earned rewards from attacker-timed donations, over-repayments, residual inventory, or other balance-side changes that should not instantly socialize across holders?
  • If the wrapper is rebase-based, cached-NAV-based, or index-based, which user-visible fields change first and which downstream solvency consumers are intentionally slower?
  • How would the protocol contain a bad recognition event after it lands: freeze collateral use, revert to a prior oracle mark, haircut the wrapper, or merely hope governance reacts before borrowers do?
  • What invariant proves the system cannot take value that is only locally or temporally true and immediately let outside modules spend, borrow against, or liquidate from it as if it were fully settled collateral truth?

Lessons that should already be standard

  • Yield exists somewhere in the system is not the same claim as all holders own it now, and that is still not the same claim as lenders may honor it as collateral right now.
  • The wrapper published a new mark is not the same claim as sibling balance sheets may lever, liquidate, or redeem against it already.
  • Published accounting truth is still not loopable debt authority; recursive-borrow rails deserve their own slower and narrower admission rule.
  • Presentation is a security boundary. Rebases, cached NAV, and balanceOf changes are not neutral UX sugar once other modules or wallets treat them as spendable truth.
  • A wrapper can be locally coherent and still globally unsafe. The lending layer usually deserves a stricter freshness policy than the wrapper itself.
  • Same-block reward recognition and same-block collateral admission are different privileges, even when they are triggered by one honest-looking rate update.
  • If a protocol cannot explain the difference between pending value, recognized value, displayed value, and borrowable value, an attacker will usually be able to collapse those states faster than reviewers expected.
  • Donation-sensitive and thin-market-sensitive reward flows are not edge noise; they are exactly where timing separation matters most.
  • The value is real is not enough. Security lives in when that value becomes canonical, who gets to act on it, and which downstream systems are allowed to believe it.
  • Healthy wrapper design is not only about pricing correctly; it is about delaying trust until the freshest plausible price is also safe for the next consumer.

Where this note stops

How to use this note with the exploit corpus

Internal linkages

Control surface