Submitted by 0xStalin, also found by Dup1337 and Jorgect
Liquidations can be DoSed which increments the risk of bad debt being generated on position.
When a liquidator is liquidating a position in WiseLending, the liquidator needs to specify the amount of shares to be repaid. The liquidation logic checks if the positions are indeed liquidable, if so, it validates if the number of shares to be liquidated exceeds the total amount of shares that can be liquidated by using the WiseSecurityHelper.checkMaxShares() function. If the amount of shares the liquidator intends to liquidate exceeds the maximum amount of liquidable shares, the execution is reverted.
The problem with this approach is that borrowers can frontrun the liquidation and repay as little as 1 share of the existing debt on the same pool that the liquidator decided to liquidate the debt from. This will cause when the liquidation is executed, the total borrow shares of the user on the pool being liquidated to be lower. If the liquidator was trying to liquidate the maximum possible amount of shares, now, the maxShares that can be liquidated will be slightly less than the amount of shares that the liquidator specified, which will cause the tx to revert.
For example, if there is a position in a liquidable state that has 100 borrowShares on the PoolA, and a liquidator decides to liquidate the maximum possible amount of shares from this position, it will send a tx to liquidate 50 shares from that position on the PoolA. The positions owner can use the WiseLending.paybackExactShares() function to repay 1 share and frontrun the liquidators tx. Now, when the liquidators tx is executed, the position is still liquidable, but it only has 99 borrowShares on the PoolA. As a result of this, the WiseSecurityHelper.checkMaxShares() function will determine that the maximum possible amount of liquidable shares is 49.5, and because the liquidator specified that he intended to liquidate 50 shares, the tx will be reverted.
In the WiseSecurityHelper.checkMaxShares() function, if the _shareAmountToPay exceeds maxShares, dont revert; re-adjust the number of shares that can be liquidated. Return the final value of _shareAmountToPay and forward it back to the WiseLending.liquidatePartiallyFromTokens() function. Then, use the final value of shareAmountToPay to compute the exact amount of tokens to be repaid in the WiseLending.liquidatePartiallyFromTokens() function.
WiseSecurity.sol:
WiseSecurityHelper.sol:
WiseLending.sol:
Context
vonMangoldt (Wise Lending) commented:
Trust (judge) commented:
vm06007 (Wise Lending) commented:
