# Rebasing token allowance unit mismatch

Allowances or balances stored in nominal units on rebasing or share-based tokens, letting spenders drain more after a rebase

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

## How it works

A token's allowance is a number, but that number only means something relative to a unit. Rebasing and share-based tokens have two units: internal shares and external token amounts, and the ratio between them moves over time. When `approve()` stores an allowance in one unit while `transferFrom()` interprets it in the other, the gap between the two units becomes free spending power. The broken assumption is that a stored allowance keeps its value; on a rebasing token it does not, because balance-per-unit changes underneath it.

## Where it shows up

- Tokens whitelisted or supported by a protocol that rebase or expose a moving `pricePerShare` (AMPL, ibBTC-style share tokens).
- `approve()` not overridden while `transfer`/`transferFrom` operate on rebalanced amounts, or vice versa.
- Router or vault code that records an allowance in nominal token units at deposit time and later approves against that stored figure.
- Public `buyFor`/`onBehalfOf` functions that pull tokens via a victim's existing allowance and mutate that victim's share or dividend accounting.

## How to review

For every ERC20 entrypoint, confirm allowance, balance, and transfer amounts all use the same unit. The invariant: the unit stored by `approve()` must equal the unit consumed by `transferFrom()`, and any stored allowance must be re-derived or invalidated when the share-to-amount ratio changes. For rebasing tokens, check whether the protocol stores nominal amounts anywhere that outlives a rebase. For `buyFor`-style functions, confirm the caller is authorized by the target and that spending an allowance cannot move the target's accounting against their interest.

## Variants seen

- Router approves rebasing AMPL by nominal amount; stale allowance after rebase drains vault deposits [E1](https://bugbountylibrary.com/r/c4%3A2024-06-thorchain%3AH-01.md).
- `approve()` stores shares while `transferFrom()` uses rebalanced amounts; spender drains more as pricePerShare grows [E3](https://bugbountylibrary.com/r/c4%3A2021-10-badgerdao%3AH-02.md).
- `buyFor` lets anyone spend victims' LINK allowances to force pool buys and inflate dividends before selling [E2](https://bugbountylibrary.com/r/dhl%3A20250618-bankrollstackplus.md).

## Impact and severity

High: direct theft of other users' deposits from a vault [E1](https://bugbountylibrary.com/r/c4%3A2024-06-thorchain%3AH-01.md), allowance inflation that grows with exchange rate [E3](https://bugbountylibrary.com/r/c4%3A2021-10-badgerdao%3AH-02.md), and dividend inflation extractable by an unprivileged caller [E2](https://bugbountylibrary.com/r/dhl%3A20250618-bankrollstackplus.md). Severity rises when the token is whitelisted protocol-wide and when existing allowances to the contract are large, since those become free capital for manipulation.

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2024-06-thorchain%3AH-01.md
- E2: https://bugbountylibrary.com/r/dhl%3A20250618-bankrollstackplus.md
- E3: https://bugbountylibrary.com/r/c4%3A2021-10-badgerdao%3AH-02.md
