#37192 [SC-Low] Trove that under MCR might be redeemed.
Submitted on Nov 28th 2024 at 08:32:15 UTC by @jasonxiale for IOP | Fluid Protocol
Report ID: #37192
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/Hydrogen-Labs/fluid-protocol/tree/main/contracts/protocol-manager-contract/src/main.sw
Impacts:
Protocol insolvency
Description
Brief/Intro
protocol-manager-contract.redeem_collateral
is supposed to work on troves with ICR >= MCR, but in current implementation, troves(whose ICR < MCR) might be redeemed.
Vulnerability Details
Quting from TroveManager.sol#L966-L969 and the comment Loop through the Troves starting from the one with lowest collateral ratio until _amount of LUSD is exchanged for collateral. We can see that in liquity's implementation
, the redeem starts first trove with ICR >= MCR, which is also the lowest collateral ratio. This applies to the our project's code in [https://github.com/Hydrogen-Labs/fluid-protocol/blob/78ab7bdd243b414b424fca6e1eb144218f36a18a/contracts/protocol-manager-contract/src/main.sw#L326-L329]:
However, in above code, there is a case that after the while loop
in protocol-manager-contractw#L326-L329, the last trove's icr might be less than MCR,in such case, the trove(icr <MCR) still will be added to current_borrowers
, and later might be redeemed.
Impact Details
Please consider the following case:
a new asset(TokenA) is added to the protocol by calling
protocol-manager-contract.register_asset
A few users start to borrow USDF using TokenA as collateral with icr a little higher than MCR
TokenA's price has fluctuated, all the troves become liquidatable(icr < MCR).
in such case, when
redeem_collateral
is called, the liquidatable troves will be redeemed.
References
https://github.com/liquity/dev/blob/e38edf3dd67e5ca7e38b83bcf32d515f896a7d2f/packages/contracts/contracts/TroveManager.sol#L966-L969 https://github.com/liquity/dev/blob/e38edf3dd67e5ca7e38b83bcf32d515f896a7d2f/packages/contracts/contracts/TroveManager.sol#L972
Proof of Concept
Proof of Concept
Please use the following patch and run
As the above output shows, when the user open a trove, the collateral's price is 1e9, and the icr is 1368159203. And then the price is changed to 0.9e9, the icr is 1231343283, but the trove can still be redeem.
we define a new price function to support 0.9e9 as price
we add a new function to show icr and owners count