# Users who deposit extra funds into their Ichi farming positions will lose all their ICHI rewards

Adding funds to an Ichi farming position in Blueberry's IchiVaultSpell burns and re-mints without refunding harvested ICHI, leaving rewards for the next closer to steal.

- Payout: Contest reward
- Severity: high
- Program: Blueberry
- Credited: carrot
- Disclosed: 2023-02-01
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-02-blueberry-judging/issues/158
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-02-blueberry%3AH-2
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** IchiVaultSpell.sol / WIchiFarm.sol farming position flow
**Root cause:** openPositionFarm() calls wIchiFarm.burn() to close existing collateral, which harvests ICHI into the Spell contract, but unlike closePositionFarm() it never calls doRefund(ICHI), so rewards stay in the contract.
**Steps:**
1. User opens Ichi farming position via `openPositionFarm()`, collateral is ERC1155 from `wIchiFarm.mint()`.
2. User calls `openPositionFarm()` again to add funds; code detects existing collSize > 0.
3. It calls `bank.takeCollateral(collSize)` then `wIchiFarm.burn(collId, collSize)`, which harvests pending ICHI to the Spell contract.
4. No `doRefund(ICHI)` follows, so ICHI balance remains in IchiVaultSpell.
5. Next user (or MEV bot) calls `closePositionFarm()`, which invokes `doRefund(ICHI)` and sweeps the stranded ICHI to themselves.
**How found:** Compared the deposit path (openPositionFarm) against the symmetric closePositionFarm path; noticed closePositionFarm explicitly calls doRefund(ICHI) after wIchiFarm.burn() while openPositionFarm does not, and traced that burn() harvests rewards into the Spell contract.
**Exploitation:** Attacker monitors the Spell contract's ICHI balance and calls closePositionFarm() (or any path invoking doRefund(ICHI)) to sweep rewards harvested from victims who topped up their positions.
**Insight:** When a protocol has paired open/close flows that both call a harvest-bearing burn(), diff the two paths for missing refund/sweep calls; any harvested token left in the contract becomes claimable by the next caller of the path that does refund.
