# User can perform sandwich attack on withdrawReserves for profit

D3Vault exchange rate rises when owner calls withdrawReserves, letting an attacker deposit before and withdraw after to profit at other users' expense.

- Payout: Contest reward
- Severity: high
- Program: Dodo
- Credited: dirk_y
- Disclosed: 2023-06-14
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-06-dodo-judging/issues/22
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-06-dodo%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:oracle-manipulation

**Target:** D3Vault withdrawReserves / exchange rate accounting
**Root cause:** exchangeRate = (cash + totalBorrows - (totalReserves - withdrawnReserves)) / dTokenSupply; withdrawReserves increases withdrawnReserves, raising the exchange rate instantly without changing real value.
**Steps:**
1. Attacker watches mempool for owner `withdrawReserves(token, amount)` call.
2. Front-run: `d3Proxy.userDeposit(user2, token, 100 ether)` to mint dTokens at the lower pre-withdraw rate.
3. Owner tx executes `d3Vault.withdrawReserves(token, reserves)`, raising exchange rate.
4. Back-run: `d3Proxy.userWithdraw(user2, token, dToken2, dTokenBalance)` redeeming dTokens at the higher rate.
5. Assert token2.balanceOf(user2) > 1000 ether, confirming profit.
**How found:** Read the inline exchangeRate formula and noticed withdrawnReserves sits in the numerator, so any owner reserve withdrawal mechanically bumps the rate; wrote a Foundry test sandwiching withdrawReserves.
**Exploitation:** Bundle deposit, owner withdrawReserves, and withdraw atomically via flashbots so no one else interleaves; profit is the exchange-rate delta on the deposited capital, taken from other vault users' share value.
**Insight:** When a share/rate formula subtracts a mutable accounting field (reserves, fees, withdrawn amounts) from the numerator, check whether an admin action changes that field in a way that instantly reprices shares — that is a sandwichable rate jump.
