Open code423n4 opened 1 year ago
trust1995 marked the issue as satisfactory
trust1995 marked the issue as primary issue
Although quite elementary, warden has made a good case. Will let sponsor weigh in.
Hi @trust1995, I agree we should change this to a <
PaprController.sol#L471. But I do not see this as high severity, I don't think.
Even with that changed, it is possible to be liquidated in the same block due to Target changing or a new oracle price. I think this is the norm for other lending protocols, e.g. I believe with Compound or Maker you could be liquidated in the same block if you max borrow and the oracle price is updated in the same block?
wilsoncusack marked the issue as disagree with severity
@wilsoncusack
I believe with Compound or Maker you could be liquidated in the same block if you max borrow and the oracle price is updated in the same block?
Other lending protocols, like Compound, Maker, and Aave, have different LTV thresholds. For example, AAVE: https://app.aave.com/reserve-overview/?underlyingAsset=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&marketName=proto_mainnet
Max LTV is the maximal debt and Liquidation threshold is the liquidation LTV. Users may borrow until max LTV but they're liquidated only after reaching the liquidation LTV. In the case of ETH, max LTV on AAVE is 82.50% and Liquidation threshold is 86.00%. The difference allows price and collateral value fluctuations, and it depends on the risk profile of an asset. For example, it's 13% for LINK: https://app.aave.com/reserve-overview/?underlyingAsset=0x514910771af9ca656af840dff83e8264ecf986ca&marketName=proto_mainnet This difference protects users from liquidations caused by high volatility.
This is a high finding because users lose funds during liquidations and every liquidation may create bad debt for the protocol. Liquidations are harmful for both protocols and users, so lending protocols shouldn't allow users to borrow themselves right into liquidations.
Thanks! TIL. My main reference was squeeth and there you can borrow right up to max (unless I miss something, again). Will consider making this change!
Because warden has demonstrated there is potentially no gap between liquidation LTV and borrow LTV, will treat this as HIGH impact. If the gap was even 1 wei I believe it would be a MED find, but the current code incentivizes MEV bots liquidating max debt positions in the same block.
trust1995 marked the issue as selected for report
Lines of code
https://github.com/with-backed/papr/blob/9528f2711ff0c1522076b9f93fba13f88d5bd5e6/src/PaprController.sol#L471 https://github.com/with-backed/papr/blob/9528f2711ff0c1522076b9f93fba13f88d5bd5e6/src/PaprController.sol#L317
Vulnerability details
Impact
Since there's no gap between the maximal LTV and the liquidation LTV, user positions may be liquidated as soon as maximal debt is taken, without leaving room for collateral and Papr token prices fluctuations. Users have no chance to add more collateral or reduce debt before being liquidated. This may eventually create more uncovered and bad debt for the protocol.
Proof of Concept
The protocol allows users to take debt up to the maximal debt, including it (PaprController.sol#L471):
However, a positions becomes liquidable as soon as user's debt reaches user's maximal debt (PaprController.sol#L317):
Moreover, the same maximal debt calculation is used during borrowing and liquidating, with the same maximal LTV (PaprController.sol#L556-L559):
Even though different price kinds are used during borrowing and liquidations (LOWER during borrowing, TWAP during liquidations), the price can in fact match (ReservoirOracleUnderwriter.sol#L11):
Which means that the difference in prices doesn't always create a gap in maximal and liquidation LTVs.
The combination of these factors allows users to take maximal debts and be liquidated immediately, in the same block. Since liquidations are not beneficial for lending protocols, such heavy penalizing of users may harm the protocol and increase total uncovered debt, and potentially lead to a high bad debt.
Tools Used
Manual review
Recommended Mitigation Steps
Consider adding a liquidation LTV that's bigger than the maximal borrow LTV; positions can only be liquidated after reaching the liquidation LTV. This will create a room for price fluctuations and let users increase their collateral or decrease debt before being liquidating. Alternatively, consider liquidating positions only after their debt has increased the maximal one: