# Attacker could steal almost all the bonus tokens in BathBuddy Vesting Wallet

BathBuddy vesting wallet pays bonus tokens by spot pool share, so a flash-loan deposit/withdraw at vesting end steals nearly all vested rewards from long-term LPs.

- Payout: Contest reward
- Severity: high
- Program: Rubicon
- Credited: xiaoming90
- Disclosed: 2022-08-01
- Write-up quality: 8/10
- Original: https://github.com/code-423n4/2022-05-rubicon-findings/issues/109
- Library page: https://bugbountylibrary.com/r/c4%3A2022-05-rubicon%3AH-03
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:flash-loan vuln:reward-distribution

**Target:** BathBuddy vesting wallet / BathToken pool reward distribution
**Root cause:** release() computes amount = releasable * sharesWithdrawn / initialTotalSupply using the user's current (spot) pool share at withdraw time, so a large transient deposit captures nearly all vested bonus tokens.
**Steps:**
1. Sponsor funds BathBuddy with 1000 DAI over 4-week linear vest; Alice and Bob each hold 50% of bathWETH pool.
2. Wait until final hour when ~998 DAI is vested.
3. Flash-loan 8500 WETH and deposit into bathWETH, gaining ~95%+ share.
4. Immediately withdraw all shares; withdraw triggers BathToken.distributeBonusTokenRewards -> BathBuddy.release with sharesWithdrawn/initialTotalSupply near 1, transferring ~997 DAI to attacker.
5. Repay flash loan; Alice later withdraws and receives only ~0.7 DAI of bonus.
**How found:** Code reading of BathBuddy.release showed reward entitlement derived from current pool share rather than time-weighted share; recognized spot-share manipulation via flash loan at end of vesting.
**Exploitation:** Atomic flash-loan: borrow large WETH, deposit to inflate pool share, withdraw in same tx to trigger release() with overwhelming sharesWithdrawn/initialTotalSupply ratio, capturing vested bonus tokens, then repay loan.
**Insight:** When a vesting/reward contract divides a vested pool by the caller's current share of an external pool, check whether that share can be inflated transiently within one transaction; time-weight or checkpoint shares to prior block.
