Submitted by Dup1337
https://github.com/code-423n4/2024-02-wise-lending/blob/79186b243d8553e66358c05497e5ccfd9488b5e2/contracts/FeeManager/FeeManager.sol#L816-L866
https://github.com/code-423n4/2024-02-wise-lending/blob/79186b243d8553e66358c05497e5ccfd9488b5e2/contracts/MainHelper.sol#L667-L727
When the pool token stops being used in the position, the _removePositionData function is called. However, it assumes that poolToken that is passed as a parameter always exists in user token array, which is not always the case. In the case of function FeeManager.paybackBadDebtNoReward(), which indirectly calls _removePositionData, insufficient validation doesnt check if repay token is in user array, which results in zeroing out information about user debt.
Free elimination of user debt.
First, lets see how MainHelper._removePositionData() works:
So, _poolToken sent in parameter is not checked if:
This function is called in MainHelper._corePayback(), which in turn is called in FeeManager.paybackBadDebtNoReward() => WiseLending.corePaybackFeeManager() => WiseLending._handlePayback(). The important factor is that paybackBadDebtNoReward() doesnt check if position utilizes  _paybackToken passed by the caller and allows it to pass any token. The only prerequisite is that badDebtPosition[_nftId] has to be bigger than 0:
With these pieces of information, we can form following attack path:
Add verification if the token that is passed to _removePositionData() exists in user tokens. If not, revert the transaction.
Invalid Validation
vonMangoldt (Wise Lending) commented:
deliriusz (warden) commented:
Trust (judge) commented:
vm06007 (Wise Lending) commented:
Foon256 (Wise Lending) commented:
Trust (judge) commented:
Alex the Entreprenerd (Appellate Court lead judge) commented:
Wise Lending commented:
