# RubiconRouter.swapEntireBalance() doesn't handle the slippage check properly

RubiconRouter.swapEntireBalance miscalculates the min-out slippage parameter by subtracting a fee from buy_amt_min, letting swaps execute below the user's intended minimum and lose funds.

- Payout: Contest reward
- Severity: high
- Program: Rubicon
- Credited: Ruhum
- Disclosed: 2022-08-01
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-05-rubicon-findings/issues/52
- Library page: https://bugbountylibrary.com/r/c4%3A2022-05-rubicon%3AH-07
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** RubiconRouter.swapEntireBalance() / _swap()
**Root cause:** swapEntireBalance computes the _swap min-out as maxAmount.sub(buy_amt_min.mul(expectedMarketFeeBPS).div(10000)) instead of passing buy_amt_min directly, so the user's slippage floor is ignored and replaced with a much lower value.
**Steps:**
1. Call swapEntireBalance(buy_amt_min=99, route, expectedMarketFeeBPS=500) with maxAmount=100.
2. Observe _swap receives min-out = 100 - (99*500/10000) = 95.05 instead of 99.
3. Swap executes accepting as little as 95.05 tokens, below the user's intended 99 minimum.
**How found:** Code reading of swapEntireBalance: noticed the second _swap argument was a computed subtraction rather than buy_amt_min, and worked a numeric example showing the effective min-out (95.05) diverges from the intended 99.
**Exploitation:** A user submits a swap expecting at least buy_amt_min tokens; because the router passes a reduced min-out to _swap, the trade can settle at a worse price, causing unintended loss of funds to the user.
**Insight:** When a wrapper forwards a user-supplied slippage bound to an inner swap, verify the exact value is passed through unchanged; fee adjustments applied to min-out silently weaken the protection.
