Users who deposit extra funds into their Ichi farming positions will lose all their ICHI rewards
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.
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
Users who farm their Ichi LP tokens for ICHI rewards can permanently lose their rewards.
```\\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