Open howlbot-integration[bot] opened 3 months ago
alex-ppg marked the issue as selected for report
alex-ppg marked the issue as satisfactory
alex-ppg changed the severity to 3 (High Risk)
The Warden has demonstrated how the stop-loss mechanism of the protocol is improperly applied only when a vault is closed in its entirety, permitting liquidators to close a vault whilst leaving a minuscule remainder within it to bypass the mechanism and thus profit at the expense of the protocol.
I believe a high severity rating is appropriate given that the vulnerability can be reliably exploited and will further deteriorate a negative market event with tangible monetary impact.
Lines of code
https://github.com/code-423n4/2024-05-predy/blob/main/src/libraries/logic/LiquidationLogic.sol#L89-L108
Vulnerability details
Impact
Description
Background
At the end of liquidation process, in the case of no remaining position,
liquidate
function checks for remaining margin of the liquidating vault.If there is positive remaining amount, it proceeds to send those margin back to vault's recipient.
On contrary, if there is
negative
remaining amount, liquidator must pay (compensate) for those negative amount.This mechanism exists to protect against protocol insolvency in the case that vault's margin cannot cover the loss from vault's position.
Liquidation incentives
Liquidators close vault's position, settle the trade and profit from slippage tolerance, set by the pool's owner.
For instance, if the slippage tolerance is set at 5% and let's say liquidator is closing this long position
Liquidator will get 1 ETH to sell for 2,500 USDC and have to return only
2500*0.95=2,375
USDC. The remaining short USDC will be deducted from vault's margin, in this case,3000-2375=625
USDCConsidering this mechanism, liquidators will always profit from the slippage.
Vulnerability
If we take a look at the snippet of the code responsible for the aforementioned protection mechanism.
LiquidationLogic.sol#L89-L108
liquidation
function only checks for negative margin if and only if the position is fully closed from liquidation.Therefore, if the position is not fully closed (99.99% closed), and left with negative margin, liquidators don't have to compensate for the loss.
Considering the case where liquidation of a full position would result in negative margin, liquidators should only be incentivized to partially close a position to the point that vault's margin becomes zero because that would be their maximum profit.
However, with the logic flaw mentioned, liquidators can increase their profit by closing nearly full position (99.99% closed), effectively leave the loss to the protocol.
Tools Used
Proof-of-Concept
This test demonstrates that liquidating nearly full position can bypass the negative margin check and leave the loss to the protocol.
Steps
2024-05-predy/test/pool/ExecLiquidationCall.t.sol
Run
forge test --match-contract TestExecLiquidationCall --match-test testLiquidateSucceedsWithNegativeMarginRemaining -vv
Recommended Mitigations
If the remaining margin in the vault is equal or less than zero, then there is no need to check whether there is still an open position because it is already effectively closed (no margin left). Therefore, a check for negative margin should be moved out from
if(!hasPosition)
block.Suggested fix
Rationale for Medium severity
Assessed type
Other