# Dust rounding bypasses minimum amount checks

Floored inputs or rates that hit zero while full value moves, skipping min-amount and slippage checks

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

## How it works
A contract computes an input amount (or an exchange rate) with integer division or fixed-point scaling, and the result floors to zero or dust. The code then checks only that the value is nonzero, or derives a minimum from the same floored value, so the check passes trivially. The counterpart amount (shares minted, funds released) is computed from the un-floored side, so real value moves for near-zero input. The broken assumption: "a nonzero input means a meaningful input," and "a rate computed from real prices is nonzero."

## Where it shows up
- Single-asset join/exit or swap functions that reverse-compute input via fixed-point weight math, mixing low-decimal tokens (8-dp) with 18-dp scaling [E1](https://bugbountylibrary.com/r/dhl%3A20260831-balancerv1bpool.md)
- Guards of the form `require(amount != 0)` or `amount <= maxAmountIn` with no minimum-effective-input or relative-error bound [E1](https://bugbountylibrary.com/r/dhl%3A20260831-balancerv1bpool.md)
- Exchange-rate helpers doing `(priceIn * scale) / priceOut` where the numerator can be smaller than the denominator [E2](https://bugbountylibrary.com/r/sherlock%3A2025-07-oku-trade-order-types%3AM-1.md)
- A `minAmountReceived` or slippage bound derived from a rate that can truncate to 0 [E2](https://bugbountylibrary.com/r/sherlock%3A2025-07-oku-trade-order-types%3AM-1.md)
- Proportional splits using base points (1e4) followed by `require(balance == 0)` [E3](https://bugbountylibrary.com/r/c4%3A2021-10-union%3AM-02.md)

## How to review
For each amount that gates value transfer, ask: can this floor to zero or dust while the other side stays full? The invariant to enforce: the effective input must be bounded below relative to the output (e.g. input >= output * rate * (1 - epsilon)), not merely nonzero. For rates, require the rate itself be nonzero and check truncation at extreme price ratios. For exact-zero assertions after integer splits, confirm the split denominator is at least as fine as token decimals, or replace the equality with a tolerance.

## Variants seen
- Reverse-computed swap input floored to 1 satoshi while full shares minted [E1](https://bugbountylibrary.com/r/dhl%3A20260831-balancerv1bpool.md)
- Exchange rate truncating to 0, zeroing minAmountReceived and disabling slippage protection [E2](https://bugbountylibrary.com/r/sherlock%3A2025-07-oku-trade-order-types%3AM-1.md)
- Base-point percentage split leaving dust that trips an exact-zero require and reverts [E3](https://bugbountylibrary.com/r/c4%3A2021-10-union%3AM-02.md)

## Impact and severity
E1 drained ~$110K and let the attacker accumulate ~99.9% of supply. E2 let a malicious keeper forge txData and steal pending order funds. E3 caused rebalancing to revert (availability). Severity rises when the floored value feeds a value-transfer path rather than a revert, and when attacker-supplied data (keeper txData) reaches the same computation.

## Why fixes fail
Evidence does not show incomplete or regressed fixes.

## Evidence
- E1: https://bugbountylibrary.com/r/dhl%3A20260831-balancerv1bpool.md
- E2: https://bugbountylibrary.com/r/sherlock%3A2025-07-oku-trade-order-types%3AM-1.md
- E3: https://bugbountylibrary.com/r/c4%3A2021-10-union%3AM-02.md
