# Double-counted value in accounting totals

Same value folded into two aggregates, or one balance backing two locks or registries

_Area: DeFi accounting and math bugs. Seen in 5 disclosed reports; one confirmed bounty: $50,000; latest 2026-03-13. Updated 2026-10-23._

## How it works
Accounting code assumes each unit of value is counted once. The assumption breaks when the same value reaches two aggregates: a balance delta applied to two totals, a term already inside a sum added again, or one `msg.value`/balance backing two independent locks. Totals then exceed reality, and later math (ratios, fees, reserves, liquidity) runs on inflated numbers.

## Where it shows up
- A helper computes a value before a state change and the same formula is reused after the mutation already absorbed the term [E3](https://bugbountylibrary.com/r/c4%3A2023-08-pooltogether%3AH-01.md).
- Two `lock()` calls inside one function each check `msg.value` independently, with no aggregate sum check [E4](https://bugbountylibrary.com/r/c4%3A2025-02-recall%3AM-03.md).
- A subtotal (e.g. an "extra" top-up) is already inside a total, yet is added to liquidity or subtracted again [E5](https://bugbountylibrary.com/r/c4%3A2024-12-benddao-invitational%3AH-01.md).
- Separate registries feeding one ratio/accounting function, so one asset can be registered twice [E2](https://bugbountylibrary.com/r/c4%3A2024-04-dyad%3AH-01.md).
- Balances keyed by token address where two addresses alias one underlying balance (proxy vs target) [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-balancer-dos-bugfix-review.md).

## How to review
For every aggregate, name the invariant: sum of components equals the total, and each unit of value is counted exactly once. Trace each add/subtract and check whether the term is already included upstream. For functions taking value, confirm one aggregate check covers all internal locks, not per-call checks. For registries, confirm an asset cannot appear in two lists feeding the same calculation. For balance-keyed maps, check whether two keys can alias one balance.

## Variants seen
- Post-mutation reuse of a pre-mutation formula [E3](https://bugbountylibrary.com/r/c4%3A2023-08-pooltogether%3AH-01.md).
- Independent `msg.value` checks backing two locks [E4](https://bugbountylibrary.com/r/c4%3A2025-02-recall%3AM-03.md).
- Subtotal already inside total, added/subtracted again [E5](https://bugbountylibrary.com/r/c4%3A2024-12-benddao-invitational%3AH-01.md).
- Same asset licensed in two registries [E2](https://bugbountylibrary.com/r/c4%3A2024-04-dyad%3AH-01.md).
- Aliased token addresses sharing one balance (adjacent: aliasing, not literal double-count) [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-balancer-dos-bugfix-review.md).

## Impact and severity
Led to drained protocol fees and DoS [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-balancer-dos-bugfix-review.md), double-counted collateral and unbacked positions [E2](https://bugbountylibrary.com/r/c4%3A2024-04-dyad%3AH-01.md), overpaid rewards [E3](https://bugbountylibrary.com/r/c4%3A2023-08-pooltogether%3AH-01.md), unbacked supply enabling fund drain [E4](https://bugbountylibrary.com/r/c4%3A2025-02-recall%3AM-03.md), and corrupted rates blocking liquidations [E5](https://bugbountylibrary.com/r/c4%3A2024-12-benddao-invitational%3AH-01.md). Severity rises when the inflated figure gates withdrawals, minting, or liquidation.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-balancer-dos-bugfix-review.md
- E2: https://bugbountylibrary.com/r/c4%3A2024-04-dyad%3AH-01.md
- E3: https://bugbountylibrary.com/r/c4%3A2023-08-pooltogether%3AH-01.md
- E4: https://bugbountylibrary.com/r/c4%3A2025-02-recall%3AM-03.md
- E5: https://bugbountylibrary.com/r/c4%3A2024-12-benddao-invitational%3AH-01.md
