Submitted by 3docSec, also found by etherhood, nmirchev8, and kfx
https://github.com/code-423n4/2024-01-opus/blob/4720e9481a4fb20f4ab4140f9cc391a23ede3817/src/core/shrine.cairo#L1046
In the Shrine implementation, the loan (trove) health is calculated by having its LTV compared to the shrine threshold:
The shrine threshold is in turn calculated from the weighted thresholds of the yang deposits, scaled down by a variable factor, in case the shrine is in recovery mode:
We can see from the above code that triggering recovery mode lowers the threshold, exposing the more under-collateralized loans (troves) to liquidation. This is expected behavior when the LTV fluctuations are coming from collateral price swings.
If we look at how recovery mode is triggered:
We can see that all it takes to trigger recovery mode is to bring the shrine LTV to 70% of its nominal threshold, or higher. This can be achieved by a malicious (or naive) user, provided they have enough collateral to take large borrows close to the collateralization threshold, and the shrine debt_ceiling provides enough headroom.
Loans can be forced into liquidation territory, and be liquidated, whenever a new loan is opened large enough to trigger recovery mode.
This can also happen as a deliberate attack, and within a single transaction, without exposing the attackers funds to liquidation. It is consequently a solid candidate for a flash loan attack, but can also be executed with a large amount of pre-deposited collateral.
The following test case can be added to test_shrine.cairo to show how a large collateral injection + large loan can force a pre-existing loan into an unhealthy state, ready to be liquidated:
Foundry
It is not entirely clear how the recovery mechanism, intended as is, can be modified to fix this issue. Introducing a form of limitation to liquidations happening in the same block of a recovery trigger can mitigate exposure to flash-loans, but large loans against pre-owned collateral left dormant on the shrine would still be a viable attack path.
What we can tell, however, is that the recovery mechanism appears to have the intent of increasing the difficulty of opening new loans as the shrine health approaches the liquidation threshold.
Popular DeFi protocols like Compound solved this very issue by having two different LTV references: one for accepting liquidations and one lower for accepting new loans.
More in detail, the protocol is vulnerable only because one can borrow at LTV values above the recovery threshold (70% of the nominal threshold) but still below the liquidation threshold. Therefore, is able to raise the global LTV above that recovery threshold. If users were not allowed to borrow above that 70%, they wouldnt be able to raise the global LTV above it, even with infinite collateral.
MEV
tserg (Opus) confirmed and commented via duplicate issue #205:
0xsomeone (judge) commented:
