Vulnerability: Users who deposit extra funds into their Ichi farming positions will lose all their ICHI rewards
Severity: high

Description:
When a user deposits extra funds into their Ichi farming position using `openPositionFarm()`, the old farming position will be closed down and a new one will be opened. Part of this process is that their ICHI rewards will be sent to the `IchiVaultSpell.sol` contract, but they will not be distributed. They will sit in the contract until the next user (or MEV bot) calls `closePositionFarm()`, at which point they will be stolen by that user.\\nWhen Ichi farming positions are opened via the `IchiVaultSpell.sol` contract, `openPositionFarm()` is called. It goes through the usual deposit function, but rather than staking the LP tokens directly, it calls `wIchiFarm.mint()`. This function deposits the token into the `ichiFarm`, encodes the deposit as an ERC1155, and sends that token back to the Spell:\\n```\\nfunction mint(uint256 pid, uint256 amount)\\n    external\\n    nonReentrant\\n    returns (uint256)\\n{\\n    address lpToken = ichiFarm.lpToken(pid);\\n    IERC20Upgradeable(lpToken).safeTransferFrom(\\n        msg.sender,\\n        address(this),\\n        amount\\n    );\\n    if (\\n        IERC20Upgradeable(lpToken).allowance(\\n            address(this),\\n            address(ichiFarm)\\n        ) != type(uint256).max\\n    ) {\\n        // We only need to do this once per pool, as LP token's allowance won't decrease if it's -1.\\n        IERC20Upgradeable(lpToken).safeApprove(\\n            address(ichiFarm),\\n            type(uint256).max\\n        );\\n    }\\n    ichiFarm.deposit(pid, amount, address(this));\\n    // @ok if accIchiPerShare is always changing, so how does this work?\\n    // it's basically just saving the accIchiPerShare at staking time, so when you unstake, it can calculate the difference\\n    // really fucking smart actually\\n    (uint256 ichiPerShare, , ) = ichiFarm.poolInfo(pid);\\n    uint256 id = encodeId(pid, ichiPerShare);\\n    _mint(msg.sender, id, amount, "");\\n    return id;\\n}\\n```\\n\\nThe resulting ERC1155 is posted as collateral in the Blueberry Bank.\\nIf the user decides to add more funds to this position, they simply call `openPositionFarm()` again. The function has logic to check if there is already existing collateral of this LP token in the Blueberry Bank. If there is, it removes the collateral and calls `wIchiFarm.burn()` (which harvests the Ichi rewards and withdraws the LP tokens) before repeating the deposit process.\\n```\\nfunction burn(uint256 id, uint256 amount)\\n    external\\n    nonReentrant\\n    returns (uint256)\\n{\\n    if (amount == type(uint256).max) {\\n        amount = balanceOf(msg.sender, id);\\n    }\\n    (uint256 pid, uint256 stIchiPerShare) = decodeId(id);\\n    _burn(msg.sender, id, amount);\\n\\n    uint256 ichiRewards = ichiFarm.pendingIchi(pid, address(this));\\n    ichiFarm.harvest(pid, address(this));\\n    ichiFarm.withdraw(pid, amount, address(this));\\n\\n    // Convert Legacy ICHI to ICHI v2\\n    if (ichiRewards > 0) {\\n        ICHIv1.safeApprove(address(ICHI), ichiRewards);\\n        ICHI.convertToV2(ichiRewards);\\n    }\\n\\n    // Transfer LP Tokens\\n    address lpToken = ichiFarm.lpToken(pid);\\n    IERC20Upgradeable(lpToken).safeTransfer(msg.sender, amount);\\n\\n    // Transfer Reward Tokens\\n    (uint256 enIchiPerShare, , ) = ichiFarm.poolInfo(pid);\\n    uint256 stIchi = (stIchiPerShare * amount).divCeil(1e18);\\n    uint256 enIchi = (enIchiPerShare * amount) / 1e18;\\n\\n    if (enIchi > stIchi) {\\n        ICHI.safeTransfer(msg.sender, enIchi - stIchi);\\n    }\\n    return pid;\\n}\\n```\\n\\nHowever, this deposit process has no logic for distributing the ICHI rewards. Therefore, these rewards will remain sitting in the `IchiVaultSpell.sol` contract and will not reach the user.\\nFor an example of how this is handled properly, we can look at the opposite function, `closePositionFarm()`. In this case, the same `wIchiFarm.burn()` function is called. But in this case, it's followed up with an explicit call to withdraw the ICHI from the contract to the user.\\n```\\ndoRefund(ICHI);\\n```\\n\\nThis `doRefund()` function refunds the contract's full balance of ICHI to the `msg.sender`, so the result is that the next user to call `closePositionFarm()` will steal the ICHI tokens from the original user who added to their farming position.

Impact:
Users who farm their Ichi LP tokens for ICHI rewards can permanently lose their rewards.

Recommended mitigation:
Issue Users who deposit extra funds into their Ichi farming positions will lose all their ICHI rewards\\nIn the `openPositionFarm()` function, in the section that deals with withdrawing existing collateral, add a line that claims the ICHI rewards for the calling user.\\n```\\nif (collSize > 0) {\\n    (uint256 decodedPid, ) = wIchiFarm.decodeId(collId);\\n    if (farmingPid != decodedPid) revert INCORRECT_PID(farmingPid);\\n    if (posCollToken != address(wIchiFarm))\\n        revert INCORRECT_COLTOKEN(posCollToken);\\n    bank.takeCollateral(collSize);\\n    wIchiFarm.burn(collId, collSize);\\n// Add the line below\\n   doRefund(ICHI);\\n}\\n```\\n