# withdrawETH() in GiantPoolBase don't call _distributeETHRewardsToUserForToken() or _onWithdraw() which would make users to lose their remaining rewards 

GiantPoolBase.withdrawETH burns LP tokens without distributing accrued ETH rewards, so users forfeit unclaimed rewards when withdrawing.

- Payout: Contest reward
- Severity: high
- Program: Stakehouse Protocol
- Credited: unforgiven
- Disclosed: 2023-01-20
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-11-stakehouse-findings/issues/260
- Library page: https://bugbountylibrary.com/r/c4%3A2022-11-stakehouse%3AH-19
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error vuln:reward-distribution

**Target:** GiantPoolBase / GiantMevAndFeesPool Solidity contracts
**Root cause:** withdrawETH() burns lpTokenETH balance without calling _distributeETHRewardsToUserForToken() or _onWithdraw(), and claimRewards() computes rewards from the now-zero balance.
**Steps:**
1. user1 deposits 10 ETH; claimed[user1][lpTokenETH]=20, accumulatedETHPerLPShare=2
2. accumulatedETHPerLPShare rises to 3; unclaimed = 10*3-20 = 10 ETH
3. user1 calls `withdrawETH(10)`; contract burns LP balance to 0 and sends 10 ETH
4. user1 calls `claimRewards()`; reward = 0 because lpTokenETH.balanceOf is 0
**How found:** Code reading: noticed withdrawETH lacks the reward-distribution/_onWithdraw hooks present in GiantMevAndFeesPool, and that claimRewards derives rewards from lpTokenETH.balanceOf.
**Exploitation:** User withdraws idle ETH via withdrawETH; the burn zeroes their LP balance before rewards are settled, permanently forfeiting accrued ETH rewards to the pool.
**Insight:** When a share/balance-based reward accumulator exists, audit every path that mutates the share balance (burn/transfer/withdraw) for a missing settle-before-mutate call; claim functions reading current balance silently zero out unclaimed rewards.
