# Zero-value edge paths in DeFi accounting

Zero amounts, zero balances, or zero bounds that skip checks, re-fire payouts, or brick accounting

_Area: DeFi accounting and math bugs. Seen in 36 disclosed reports; latest 2026-06-23. Updated 2026-10-23._

## How it works
Accounting code assumes a quantity is nonzero, a balance implies membership, or a bound is ordered. The invariant that breaks: a value-moving branch fires exactly once, on a real quantity, with every field it reads consistent. Five shapes break it:

- **Zero quantity still mutates state.** A transfer/burn hook updates per-user or per-tier bookkeeping for every item, including `amount==0`, so a no-op transfer changes balances [E1](https://bugbountylibrary.com/r/dhl%3A20260623-royalroyalties.md)[E2](https://bugbountylibrary.com/r/c4%3A2024-02-althea-liquid-infrastructure%3AH-01.md).
- **Zero value doubles as an existence sentinel.** A mapping's zero value means "absent," but a write path can legitimately store zero, so later reads treat a real record as missing [E3](https://bugbountylibrary.com/r/c4%3A2023-12-autonolas%3AH-05.md).
- **A required record is skipped on a zero input.** A valuation loop requires a per-item record that a zero-balance path never creates, so the view reverts [E6](https://bugbountylibrary.com/r/sherlock%3A2025-06-notional-exponent%3AM-25.md).
- **A zero bound or zero denominator skips a constraint.** A time-window of zero lets a payout denominator change after distribution [E4](https://bugbountylibrary.com/r/c4%3A2023-10-wildcat%3AH-04.md); a zero denominator early-returns past a ratio limit [E8](https://bugbountylibrary.com/r/c4%3A2024-04-panoptic%3AM-04.md).
- **A zero current balance short-circuits a nonzero target.** A rebalance check returns "no action" when collateral is zero, even though the target is nonzero [E7](https://bugbountylibrary.com/r/sherlock%3A2024-08-perennial-v2-update-3%3AM-3.md).

## Where it shows up
- Transfer/burn hooks that mutate per-user or membership state on every item, including `amount==0`, keyed on a `balanceOf` existence check [E1](https://bugbountylibrary.com/r/dhl%3A20260623-royalroyalties.md)[E2](https://bugbountylibrary.com/r/c4%3A2024-02-althea-liquid-infrastructure%3AH-01.md).
- Mappings where zero is the existence sentinel, written by a path that only checks an upper bound [E3](https://bugbountylibrary.com/r/c4%3A2023-12-autonolas%3AH-05.md).
- Valuation loops requiring a per-item record that a zero-balance path skips creating [E6](https://bugbountylibrary.com/r/sherlock%3A2025-06-notional-exponent%3AM-25.md).
- Time-window parameters that can be zero, letting a payout denominator change after distribution [E4](https://bugbountylibrary.com/r/c4%3A2023-10-wildcat%3AH-04.md).
- Ratio/limit checks that early-return on a zero denominator while the numerator is positive [E8](https://bugbountylibrary.com/r/c4%3A2024-04-panoptic%3AM-04.md).
- Rebalance checks that short-circuit on a zero current balance despite a nonzero target [E7](https://bugbountylibrary.com/r/sherlock%3A2024-08-perennial-v2-update-3%3AM-3.md).
- Wrappers that reuse a caller-supplied amount where zero means "use full amount" downstream [E5](https://bugbountylibrary.com/r/sherlock%3A2024-02-tapioca%3AH-12.md).

## How to review
For each value-moving branch ask: can it be reached with a zero or degenerate input, and does it fire more than once? Grep targets: `balanceOf(...) != 0` existence checks, `amount > 0` guards, `== 0` early returns, `liquidity <= max` without `> 0`, `require(hasRequest)` loops, and `tapAmount`-style sentinel parameters. Verify hooks skip state mutation when `amount==0` and track membership explicitly, not via balance [E1](https://bugbountylibrary.com/r/dhl%3A20260623-royalroyalties.md)[E2](https://bugbountylibrary.com/r/c4%3A2024-02-althea-liquid-infrastructure%3AH-01.md). Verify every write path that can store zero is matched by the read that treats zero as absent [E3](https://bugbountylibrary.com/r/c4%3A2023-12-autonolas%3AH-05.md). Verify a zero time-window cannot leave a payout denominator mutable after distribution [E4](https://bugbountylibrary.com/r/c4%3A2023-10-wildcat%3AH-04.md). Verify a zero denominator does not skip a limit while the numerator is positive [E8](https://bugbountylibrary.com/r/c4%3A2024-04-panoptic%3AM-04.md). Verify a zero current balance does not short-circuit a nonzero target [E7](https://bugbountylibrary.com/r/sherlock%3A2024-08-perennial-v2-update-3%3AM-3.md). Verify wrappers measure realized balance delta rather than trusting a sentinel parameter [E5](https://bugbountylibrary.com/r/sherlock%3A2024-02-tapioca%3AH-12.md). False positives: zero-amount calls that revert or are true no-ops with no state write are safe; a zero-collateral market may be legitimately idle when no target is set [E7](https://bugbountylibrary.com/r/sherlock%3A2024-08-perennial-v2-update-3%3AM-3.md); a zero time-window may be an intended instant-close if the denominator is frozen first [E4](https://bugbountylibrary.com/r/c4%3A2023-10-wildcat%3AH-04.md).

## Variants seen
- Zero-amount ERC1155 batch inflates tier balance, draining deposits [E1](https://bugbountylibrary.com/r/dhl%3A20260623-royalroyalties.md).
- Zero-amount transfer/burn duplicates holder entries via `balanceOf!=0` [E2](https://bugbountylibrary.com/r/c4%3A2024-02-althea-liquid-infrastructure%3AH-01.md).
- Zero-liquidity deposit stored where zero means absent, freezing withdrawals [E3](https://bugbountylibrary.com/r/c4%3A2023-12-autonolas%3AH-05.md).
- Zero batch duration lets denominator grow after payout [E4](https://bugbountylibrary.com/r/c4%3A2023-10-wildcat%3AH-04.md).
- Sentinel `tapAmount=0` leaves exercised output frozen in the wrapper [E5](https://bugbountylibrary.com/r/sherlock%3A2024-02-tapioca%3AH-12.md).
- Zero exit balance skips request creation, bricking valuation [E6](https://bugbountylibrary.com/r/sherlock%3A2025-06-notional-exponent%3AM-25.md).
- Zero-collateral market skipped despite nonzero target [E7](https://bugbountylibrary.com/r/sherlock%3A2024-08-perennial-v2-update-3%3AM-3.md).
- Zero netLiquidity early return bypasses spread limit [E8](https://bugbountylibrary.com/r/c4%3A2024-04-panoptic%3AM-04.md).

## Impact and severity
Contract-held asset drains [E1](https://bugbountylibrary.com/r/dhl%3A20260623-royalroyalties.md), reward theft and distribution DoS [E2](https://bugbountylibrary.com/r/c4%3A2024-02-althea-liquid-infrastructure%3AH-01.md), frozen withdrawals and bricked accounts [E3](https://bugbountylibrary.com/r/c4%3A2023-12-autonolas%3AH-05.md)[E6](https://bugbountylibrary.com/r/sherlock%3A2025-06-notional-exponent%3AM-25.md), over-withdrawal from a batch [E4](https://bugbountylibrary.com/r/c4%3A2023-10-wildcat%3AH-04.md), frozen user output [E5](https://bugbountylibrary.com/r/sherlock%3A2024-02-tapioca%3AH-12.md), skipped rebalancing [E7](https://bugbountylibrary.com/r/sherlock%3A2024-08-perennial-v2-update-3%3AM-3.md), unpaid premium [E8](https://bugbountylibrary.com/r/c4%3A2024-04-panoptic%3AM-04.md). Severity rises when the zero path is cheap to trigger and the payout is large relative to contract assets, as in the 261k USDC drain [E1](https://bugbountylibrary.com/r/dhl%3A20260623-royalroyalties.md).

## Evidence
- E1: https://bugbountylibrary.com/r/dhl%3A20260623-royalroyalties.md
- E2: https://bugbountylibrary.com/r/c4%3A2024-02-althea-liquid-infrastructure%3AH-01.md
- E3: https://bugbountylibrary.com/r/c4%3A2023-12-autonolas%3AH-05.md
- E4: https://bugbountylibrary.com/r/c4%3A2023-10-wildcat%3AH-04.md
- E5: https://bugbountylibrary.com/r/sherlock%3A2024-02-tapioca%3AH-12.md
- E6: https://bugbountylibrary.com/r/sherlock%3A2025-06-notional-exponent%3AM-25.md
- E7: https://bugbountylibrary.com/r/sherlock%3A2024-08-perennial-v2-update-3%3AM-3.md
- E8: https://bugbountylibrary.com/r/c4%3A2024-04-panoptic%3AM-04.md
