# Sandwichable pool ratio and slippage

Spot-reserve pricing, caller-controlled slippage, or pre-swap health checks that let a sandwich shift value

_Area: DeFi oracles, liquidations and flash loans. Seen in 4 disclosed reports; one confirmed bounty: $800,000; latest 2025-04-16. Updated 2026-11-02._

## How it works
A protocol prices an action (deposit, swap, leverage check) off the pool's *current* reserves or accepts a caller-supplied slippage bound. An attacker who can move those reserves within one transaction (often with flash-loaned capital) makes the protocol trade at a distorted ratio, then unwinds the distortion for profit. The broken assumption: that spot reserves and caller-set slippage reflect fair value. They don't when the caller controls both the trade and the price.

## Where it shows up
- `addLiquidity`/`addLiquidityETH` calls with 100% (or absent) slippage tolerance [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-fei-protocol-flashloan-vulnerability-bugfix-review.md)
- Swap functions with no `minAmountOut`/`maxAmountIn` enforcement [E2](https://bugbountylibrary.com/r/dhl%3A20250416-ybtoken.md)
- AMMs allowing imbalanced deposits where LP minted uses spot reserves [E3](https://bugbountylibrary.com/r/c4%3A2023-07-basin%3AM-11.md)
- Health/leverage checks that run *before* a price-sensitive swap, with no post-swap re-check [E4](https://bugbountylibrary.com/r/sherlock%3A2023-06-unstoppable%3AH-3.md)
- Caller-supplied slippage parameters on borrow-and-swap flows [E4](https://bugbountylibrary.com/r/sherlock%3A2023-06-unstoppable%3AH-3.md)
- `isContract`/`extcodesize` guards meant to block bots [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-fei-protocol-flashloan-vulnerability-bugfix-review.md)

## How to review
Find every place value is computed from pool reserves or a caller-supplied slippage value. The invariant: **the amount received or credited must be bounded by a price the caller cannot move in the same transaction** (a TWAP, a signed oracle, or a hard slippage cap). Check that:
- Slippage limits are non-zero and enforced on-chain, not passed through from the caller [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-fei-protocol-flashloan-vulnerability-bugfix-review.md)[E2](https://bugbountylibrary.com/r/dhl%3A20250416-ybtoken.md).
- LP minting for imbalanced deposits uses a ratio that a single large deposit cannot skew against the next depositor [E3](https://bugbountylibrary.com/r/c4%3A2023-07-basin%3AM-11.md).
- Any leverage/health check is re-evaluated *after* the swap, against actual output, not pre-swap intent [E4](https://bugbountylibrary.com/r/sherlock%3A2023-06-unstoppable%3AH-3.md).
- "No contracts" guards don't rely on `extcodesize`, which is zero during construction [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-fei-protocol-flashloan-vulnerability-bugfix-review.md).

## How finders spotted it
- Noticed `allocate()` was permissionless, deposited at oracle price with 100% slippage, and that the `isContract` guard returns false inside a constructor [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-fei-protocol-flashloan-vulnerability-bugfix-review.md).
- Saw the swap function lacked slippage checks, enabling reserve manipulation via repeated swaps [E2](https://bugbountylibrary.com/r/dhl%3A20250416-ybtoken.md).
- Reasoned that imbalanced liquidity adds are allowed and LP minting depends on spot reserves, then PoC'd a sandwich [E3](https://bugbountylibrary.com/r/c4%3A2023-07-basin%3AM-11.md).
- Code review: `max_leverage` checked before the swap, slippage caller-controlled, no post-swap liquidity check — a stale health check [E4](https://bugbountylibrary.com/r/sherlock%3A2023-06-unstoppable%3AH-3.md).

## Variants seen
- Protocol deposits into a pool at a flash-loan-distorted ratio [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-fei-protocol-flashloan-vulnerability-bugfix-review.md)
- Token swap with no slippage bound, reserves drained by repeated swaps [E2](https://bugbountylibrary.com/r/dhl%3A20250416-ybtoken.md)
- Front-run imbalanced deposit, victim deposits, attacker redeems [E3](https://bugbountylibrary.com/r/c4%3A2023-07-basin%3AM-11.md)
- Self-sandwich on borrow-and-swap to manufacture bad debt [E4](https://bugbountylibrary.com/r/sherlock%3A2023-06-unstoppable%3AH-3.md)

## Impact and severity
Up to 60,000 ETH drainable in Fei [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-fei-protocol-flashloan-vulnerability-bugfix-review.md); 15,261 BUSD in YVToken [E2](https://bugbountylibrary.com/r/dhl%3A20250416-ybtoken.md); ~28% of victim funds per sandwich in Basin [E3](https://bugbountylibrary.com/r/c4%3A2023-07-basin%3AM-11.md); bad-debt positions in Unstoppable [E4](https://bugbountylibrary.com/r/sherlock%3A2023-06-unstoppable%3AH-3.md). Impact scales with attacker capital (flash loans amplify it) and repeatability; combining a manipulable ratio with a bypassable guard or a stale check raises severity sharply [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-fei-protocol-flashloan-vulnerability-bugfix-review.md)[E4](https://bugbountylibrary.com/r/sherlock%3A2023-06-unstoppable%3AH-3.md).

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-fei-protocol-flashloan-vulnerability-bugfix-review.md
- E2: https://bugbountylibrary.com/r/dhl%3A20250416-ybtoken.md
- E3: https://bugbountylibrary.com/r/c4%3A2023-07-basin%3AM-11.md
- E4: https://bugbountylibrary.com/r/sherlock%3A2023-06-unstoppable%3AH-3.md
