# Pool deviation check in SimpleManager on rebalance can be bypassed

Malicious Arrakis operator bypasses SimpleManager pool deviation check via a poison token callback during router swap, then adds liquidity at a skewed price and backruns to drain vault funds.

- Payout: Contest reward
- Severity: high
- Program: Arrakis
- Credited: cergyk
- Disclosed: 2023-06-05
- Write-up quality: 8/10
- Original: https://github.com/sherlock-audit/2023-06-arrakis-judging/issues/26
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-06-arrakis%3AH-1
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:business-logic vuln:flash-loan vuln:oracle-manipulation

**Target:** SimpleManager.rebalance / ArrakisV2 router swap
**Root cause:** Price deviation is checked before the router swap, but the swap can call an attacker-controlled token whose _transfer callback manipulates the UniV3 pool price; the deviation check is never re-enforced before addLiquidity.
**Steps:**
1. Operator calls `SimpleManager.rebalance` with a whitelisted router payload swapping on attacker-controlled `PSN/PSN2` pool
2. Deviation check at L366-385 passes since target pool not yet skewed
3. Router swap triggers `PSN._transfer` callback which performs a large swap on the victim UniV3 pool, skewing its price
4. Vault balances unchanged so post-swap slippage check passes
5. `addLiquidity` at step 5 executes at the skewed unfavorable price
6. Operator backruns to extract value; all steps wrapped in a flashloan callback
**How found:** Code review of rebalance ordering: noticed deviation check occurs before the arbitrary router call, and that the router payload is never decoded, so any token contract invoked during the swap can mutate pool state between the check and addLiquidity.
**Exploitation:** Malicious operator crafts rebalance payload routing through a poison token pool; the token's transfer hook skews the target UniV3 pool after the deviation check but before liquidity provision, letting the operator sandwich their own rebalance and drain vault funds without own capital via flashloan.
**Escalation:** Unbounded drain since operator controls payload and can repeat per rebalance; flashloan removes capital requirement.
**Insight:** When a slippage/deviation check precedes an arbitrary external call (router swap), look for state-mutating callbacks (ERC20 transfer hooks, reentrancy) that can move the price after the check but before the guarded action; also note unchecked operator-supplied addLiquidity min amounts defaulting to (0,0).
