# Unset baseline counts pre-existing balance as yield

Delta-based yield or balance math where the snapshot baseline is unset, stale, or inferred from a parameter

_Area: DeFi accounting and math bugs. Seen in 4 disclosed reports; latest 2025-08-11. Updated 2026-10-24._

## How it works
Yield and balance accounting often uses a delta: measure a balance before an action, measure again after, and treat the difference as new value. That is only correct if the "before" snapshot is real and taken at the right moment. When the baseline is never assigned (stays zero), is inferred from an approved parameter instead of measured, or is not updated when tokens leave, the delta absorbs funds that were already there. Pre-existing user holdings, unused approvals, or already-claimed tokens get reclassified as fresh yield or fresh principal, and downstream collateral, recovery, or withdrawal math trusts the inflated number.

## Where it shows up
- `balanceBefore`/`balanceAfter` delta patterns where the snapshot field is declared but never assigned before the transfer.
- Held-balance computed as `totalSupply - approvedAmount` rather than measured `balanceOf` after the initializer runs.
- Excess/recovery formulas (`balanceOf - (deposit - redeemed)`) that assume a claim path left state variables untouched.
- Two-step cooldown/claim flows where the claim ratio comes from a caller-supplied `shares` argument, not the queued amount.
- Any function that moves tokens out without mutating the variables later balance math depends on.

## How to review
The invariant: every delta baseline must be a real, freshly measured value, and every outflow must update the state that later balance math reads. Check that each `balanceBefore` is assigned immediately before the transfer it precedes; that held amounts are measured via `balanceOf` delta, not inferred from an approved parameter; and that each token-moving function (claim, recover, unstake) mutates the accounting variables used by recovery and collateral logic. Trace the inflated value into its consumer (collateral, borrow limit, recovery payout) to confirm impact.

## Variants seen
- Unset `balanceBefore` (stays 0) counts recipient's whole pre-existing balance as yield, inflating collateral [E1](https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.1.4.md).
- Held balance inferred from approved `numTokensToSell` instead of consumed amount, locking unused tokens [E2](https://bugbountylibrary.com/r/cantina%3Adoppler%3A3.1.7.md).
- Claim path moves tokens out without updating `depositTokenAmount`/`redeemedDepositTokens`, breaking recovery excess math [E3](https://bugbountylibrary.com/r/c4%3A2021-11-streaming%3AH-10.md).
- Withdrawal ratio from user-supplied shares instead of cooled-down shares, booking principal as yield [E4](https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.1.8.md).

## Impact and severity
Led to undercollateralized over-borrowing [E1](https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.1.4.md), permanently locked assets [E2](https://bugbountylibrary.com/r/cantina%3Adoppler%3A3.1.7.md), broken recovery [E3](https://bugbountylibrary.com/r/c4%3A2021-11-streaming%3AH-10.md), and double-counted collateral [E4](https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.1.8.md). Severity is high where the inflated number feeds borrowing limits or irreversible recovery; worse when the bad value persists across calls.

## Evidence
- E1: https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.1.4.md
- E2: https://bugbountylibrary.com/r/cantina%3Adoppler%3A3.1.7.md
- E3: https://bugbountylibrary.com/r/c4%3A2021-11-streaming%3AH-10.md
- E4: https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.1.8.md
