# AutoPooledTradingBot: double withdrawal via unburned shares

AutoPooledTradingBot's withdrawInvestment paid out without burning shares, letting attacker double-withdraw via emergencyWithdrawAll for 0.15 ETH profit.

- Payout: Real-world hack
- Severity: high
- Program: AutoPooledTradingBot
- Credited: DeFiHackLabs
- Disclosed: 2025-08-17
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2025-08/AutoPooledTradingBot_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20250817-autopooledtradingbot
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity vuln:accounting-error vuln:business-logic

**Target:** AutoPooledTradingBot smart contract (deposit/withdrawInvestment/emergencyWithdrawAll)
**Root cause:** withdrawInvestment pays from totalInvested but does not burn shares or reduce pool accounting, leaving emergencyWithdrawAll able to pay the same position again.
**Steps:**
1. Flash-borrow 0.192 WETH from WETH-SPX UniswapV2 pair via `swap(borrowAmount, 0, address(this), data)`.
2. In `uniswapV2Call`, unwrap WETH to ETH and call `deposit{value: amount0}(address(0))` on the vulnerable contract.
3. Call `withdrawInvestment(0)` to receive 90% of the deposit while shares remain.
4. Call `emergencyWithdrawAll()` to withdraw the still-existing shares again.
5. Repay flash swap: `repayAmount = (amount0 * 1000) / 997 + 1`, wrap ETH to WETH and transfer to pair.
6. Send remaining ETH profit to attacker.
**How found:** Attacker likely noticed that withdrawInvestment did not reduce share balance or totalInvested, allowing a second withdrawal through emergencyWithdrawAll for the same deposit.
**Exploitation:** Attacker used a Uniswap V2 flash swap to borrow 0.192 WETH with no upfront capital, deposited it into AutoPooledTradingBot, withdrew 90% via withdrawInvestment without shares being burned, then called emergencyWithdrawAll to drain the same position again, repaid the flash loan, and kept ~0.15 ETH profit.
**Insight:** In DeFi contracts, check whether withdrawal functions properly burn shares or update accounting; any path that pays out without reducing the user's share balance enables double-withdrawal, especially when combined with emergency functions.
