# boostDelegate can steal reward from user due to insufficient slippage protection

BoostDelegate frontruns a user's batchClaimRewards, consuming shared boost so the user gets ~50% less reward yet still pays the delegate fee.

- Payout: Contest reward
- Severity: high
- Program: Bima
- Credited: T1MOH
- Disclosed: 2025-02-05
- Write-up quality: 7/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_bima_december2024.pdf#3.1.6
- Library page: https://bugbountylibrary.com/r/cantina%3Abima_december2024%3A3.1.6
- Tags: domain:web3 impact:funds-loss kind:contest platform:cantina sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** BimaVault.batchClaimRewards / boost delegation
**Root cause:** Slippage protection only checks feePct <= maxFeePct, not the resulting boosted amount, so a delegate can consume the shared boost pool before the user's tx and the user still pays the fee.
**Steps:**
1. Lock Bima for user and boostDelegate, register receiver, both vote MAX_POINTS.
2. boostDelegate calls `setBoostDelegationParams(true, 1000, address(0))` (10% fee).
3. Allocate emissions; user computes expected `claimableRewardAfterBoost` (~9.39e26).
4. boostDelegate frontruns with `batchClaimRewards(boostDelegate, address(0), rewardContracts, 0)` consuming all boost.
5. User's `batchClaimRewards` executes: fee check passes but adjustedAmount drops to ~5.37e26 while fee still charged.
**How found:** Reviewer read _transferAllocated and noticed the only slippage guard is fee <= maxFeePct, which does not capture the boost consumption state that determines actual payout.
**Exploitation:** Malicious delegate with large boost weight frontruns any user relying on its delegation, claims its own boosted rewards first, leaving zero boost; user's tx still passes maxFeePct check and pays fee for no boost.
**Insight:** When a shared/consumable resource (boost, quota, allowance) determines payout, slippage guards must bound the output amount, not just the fee; check for guards that ignore mutable shared state a counterparty can drain first.
