# Bazaar: missing permission check in exitPool drains 1.4M

Bazaar's Balancer vault lacked permission checks on exitPool, letting an attacker drain 1.4M by specifying an arbitrary holder and pool ID.

- Payout: Real-world hack
- Severity: critical
- Program: Bazaar
- Credited: DeFiHackLabs
- Disclosed: 2024-06-10
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2024-06/Bazaar_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20240610-bazaar
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:critical tech:evm tech:solidity vuln:access-control vuln:business-logic

**Target:** Balancer vault contract (exitPool function)
**Root cause:** The vulnerable vault contract failed to verify that the caller was authorized to exit a pool on behalf of the specified holder, allowing anyone to call exitPool with an arbitrary holder address and pool ID.
**Steps:**
1. Fork Blast at block 4619716.
2. Call `vulnVault.exitPool(TARGET_ID, HOLDER_TO_TAKE_FROM, payable(address(this)), request)` where TARGET_ID is the pool ID and HOLDER_TO_TAKE_FROM is the victim's address.
3. Construct ExitPoolRequest with assets [WETH, RYOLO], minAmountsOut [0,0], and userData `abi.encode(1, MAX_ETH_OUT)` to request maximum ETH out.
4. Receive 392.368916743742801361 ETH (worth ~1.4M) in the attacker contract.
**Exploitation:** Attacker directly called the vulnerable vault's exitPool function, specifying a victim holder address and a pool ID, bypassing permission checks to withdraw the victim's share of the pool as ETH.
**Insight:** When auditing vault or pool contracts that implement exit/withdraw functions, check whether the caller is authorized to act on behalf of the holder; missing access control on such functions allows draining any user's position.
