# Token decimals not normalized in accounting

Amounts from tokens or oracles with different decimal scales summed, compared, or scaled without conversion

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

## How it works

Every amount carries an implicit unit: a token's native decimals, an oracle's fixed 1e18 rate, a Uniswap X96 factor, or a raw percentage. Code that combines amounts assumes both sides share a unit. When one side is in redeem-token decimals and the other in borrow-token decimals, or an oracle rate (1e18) is multiplied by a token amount without normalizing that amount to the output token's decimals, the result is silently off by a power of ten. Nothing reverts; the wrong number flows into valuation, collateral, rewards, or fees.

## Where it shows up

- A value function multiplying a token amount by an oracle rate (1e18) and dividing only by a precision constant, never converting token decimals [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-leveraged-vaults%3AH-5.md).
- Multiple fixed-point constants in one comparison (Uniswap 2**96 vs 1e18) [E2](https://bugbountylibrary.com/r/sherlock%3A2024-04-teller-finance%3AH-6.md).
- Scaling by `10**(18 - vToken.decimals())` when the underlying token's decimals are what matter [E3](https://bugbountylibrary.com/r/c4%3A2023-09-venus%3AH-03.md).
- A quote denominated in one token's decimals used directly as another token's units at settlement [E4](https://bugbountylibrary.com/r/dhl%3A20260421-kipselipropamm.md).
- A 1e16-scaled value compared against a raw percentage [E6](https://bugbountylibrary.com/r/c4%3A2026-01-olas%3AM-04.md).
- A fee computed in token units passed to a consumer that reads it as basis points [E7](https://bugbountylibrary.com/r/dhl%3A20260110-futureswap.md).
- Duplicated math where one copy was fixed for decimals and the sibling was not [E8](https://bugbountylibrary.com/r/cantina%3Aaquarius_aug2025%3A3.2.4.md).
- A scaling step omitted on one path (token-to-LP) but present on its mirror [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-leveraged-vaults%3AH-5.md).
- Grep heuristic: `1e18`, `2**96`, `10**`, `decimals()` near any amount that is summed, compared, or transferred.

## How to review

For each amount, name its unit explicitly (token decimals, 1e18 oracle rate, X96, bps) and confirm every consumer expects that unit. The invariant: both sides of any comparison, sum, or transfer are in the same decimals, and normalization is applied exactly once. Checklist: (1) when an oracle rate meets a token amount, verify the amount is normalized to the output token's decimals [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-leveraged-vaults%3AH-5.md); (2) verify the scaling site uses the correct token's decimals, not a wrapper's [E3](https://bugbountylibrary.com/r/c4%3A2023-09-venus%3AH-03.md); (3) check quote-vs-settlement units on cross-decimal routes [E4](https://bugbountylibrary.com/r/dhl%3A20260421-kipselipropamm.md); (4) diff sibling implementations and mirror paths of the same math [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-leveraged-vaults%3AH-5.md)[E8](https://bugbountylibrary.com/r/cantina%3Aaquarius_aug2025%3A3.2.4.md); (5) confirm the unit contract of values crossing into shared managers (token amount vs bps vs WAD) [E7](https://bugbountylibrary.com/r/dhl%3A20260110-futureswap.md).

## Variants seen

- Oracle rate times unnormalized token amount [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-leveraged-vaults%3AH-5.md).
- Mixed fixed-point constants in one comparison [E2](https://bugbountylibrary.com/r/sherlock%3A2024-04-teller-finance%3AH-6.md).
- Wrong token's decimals used for scaling [E3](https://bugbountylibrary.com/r/c4%3A2023-09-venus%3AH-03.md).
- Quote in one token's units settled as another's [E4](https://bugbountylibrary.com/r/dhl%3A20260421-kipselipropamm.md).
- Scaled value compared to raw percentage [E6](https://bugbountylibrary.com/r/c4%3A2026-01-olas%3AM-04.md).
- Token-unit fee read as basis points [E7](https://bugbountylibrary.com/r/dhl%3A20260110-futureswap.md).
- Unfixed duplicate of fixed decimal math [E8](https://bugbountylibrary.com/r/cantina%3Aaquarius_aug2025%3A3.2.4.md).
- Missing scaling on one asymmetric path [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-leveraged-vaults%3AH-5.md).

## Impact and severity

Over-borrowing from inflated collateral [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-leveraged-vaults%3AH-5.md)[E2](https://bugbountylibrary.com/r/sherlock%3A2024-04-teller-finance%3AH-6.md), zeroed rewards [E3](https://bugbountylibrary.com/r/c4%3A2023-09-venus%3AH-03.md), drained swap output [E4](https://bugbountylibrary.com/r/dhl%3A20260421-kipselipropamm.md), blocked migration [E6](https://bugbountylibrary.com/r/c4%3A2026-01-olas%3AM-04.md), fee-vault drain [E7](https://bugbountylibrary.com/r/dhl%3A20260110-futureswap.md), inflated pool rewards [E8](https://bugbountylibrary.com/r/cantina%3Aaquarius_aug2025%3A3.2.4.md), ~$11m pool drain [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-leveraged-vaults%3AH-5.md). Severity rises when the mismatch feeds value transfer or liquidation rather than a revert.

## Evidence
- E1: https://bugbountylibrary.com/r/sherlock%3A2024-06-leveraged-vaults%3AH-5.md
- E2: https://bugbountylibrary.com/r/sherlock%3A2024-04-teller-finance%3AH-6.md
- E3: https://bugbountylibrary.com/r/c4%3A2023-09-venus%3AH-03.md
- E4: https://bugbountylibrary.com/r/dhl%3A20260421-kipselipropamm.md
- E5: https://bugbountylibrary.com/r/c4%3A2023-07-tapioca%3AH-24.md
- E6: https://bugbountylibrary.com/r/c4%3A2026-01-olas%3AM-04.md
- E7: https://bugbountylibrary.com/r/dhl%3A20260110-futureswap.md
- E8: https://bugbountylibrary.com/r/cantina%3Aaquarius_aug2025%3A3.2.4.md
