# attackers will keep stealing the `rewards` from Convex SPELL

ConvexSpell.openPositionFarm only refunds CVX after burning Convex LP, leaving CRV and extra rewards stranded in the spell for anyone to sweep.

- Payout: Contest reward
- Severity: high
- Program: Blueberry
- Credited: Bauer
- Disclosed: 2023-04-07
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-04-blueberry-judging/issues/101
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-04-blueberry%3AH-1
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:solidity technique:source-review vuln:accounting-error vuln:reward-distribution

**Target:** ConvexSpell / WConvexPools wrapper (Solidity)
**Root cause:** WConvexPools.burn() transfers CRV, CVX and extra incentive tokens to the spell, but ConvexSpell only calls _doRefundRewards(CVX), so CRV and other reward tokens remain in the spell contract.
**Steps:**
1. Open a farm position via ConvexSpell.openPositionFarm() with Convex LP collateral.
2. Close it via closePositionFarm(): bank.takeCollateral then wConvexPools.burn() sends CRV+CVX+extra rewards to the spell.
3. Observe only _doRefundRewards(CVX) is called; CRV and extra tokens stay in the spell.
4. Any caller invokes _doRefund() with the same token addresses to sweep the stranded rewards.
**How found:** Code reading: compared WConvexPools.burn() reward transfer loop against ConvexSpell.openPositionFarm's single _doRefundRewards(CVX) call, spotting the mismatch in refunded token set.
**Exploitation:** Attacker waits for users to close positions (or triggers closes), then calls the refund path with the stranded reward token addresses to drain CRV/extra rewards accumulated in the spell.
**Insight:** When a wrapper forwards multiple reward tokens on burn, audit the spell's refund list against the wrapper's actual transfer set — a single-token refund leaves the rest sweepable by anyone.
