#37607 [SC-Low] bricking redeem function
Was this helpful?
Was this helpful?
Submitted on Dec 10th 2024 at 12:11:56 UTC by @Blockian for
Report ID: #37607
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
Permanent freezing of funds
A critical issue in the redeem_collateral
function causes it to always revert, effectively preventing the redemption of USDF. This renders the redeem_collateral
functionality inoperable under certain conditions.
The problem originates from the get_all_assets_info
function. Specifically, when it attempts to populate the current borrower for a specific asset, it calls trove_manager.get_current_icr
for the candidate current_borrower
. If this call is made for a non-existent identity (e.g., null_identity_address
), the function reverts.
This behavior occurs because trove_manager.get_current_icr
tries to read from an uninitialized storage address, resulting in a revert in Sway. The chain of function calls leading to this issue is as follows:
trove_manager.get_current_icr
→ internal_get_current_icr
→ internal_get_entire_debt_and_coll
→ internal_get_pending_asset_reward
.
The problematic code snippet:
The get_all_assets_info
function calls trove_manager.get_current_icr
with the candidate current_borrower
has an ICR lower than the MCR. In this case, the function fetches the previous borrower using sorted_troves.get_prev
. If the previous borrower is null
, it results in a revert.
Relevant code snippet:
This issue arises when all borrowers in a specific trove have an ICR below the MCR. This scenario can occur due to:
Sudden token price drops (e.g., rug pulls, de-pegging, or hacks).
Other events leading to a significant decrease in collateral value.
While the likelihood of this issue may seem low, the protocol's support for a wide variety of tokens—along with future additions—amplifies the probability of encountering such a situation over time.
The inability to call redeem_collateral
disrupts the protocol's core functionality. A potential workaround could involve liquidating the entire trove. However, the protocol enforces a constraint (require_more_than_one_trove_in_system
) that prevents liquidating all troves. As a result, the affected trove cannot be liquidated, leaving the redeem_collateral
function effectively bricked.
Modify the behavior of trove_manager.get_current_icr
to return u64::max
when called for a non-existent trove. This change ensures the function handles edge cases gracefully, avoiding reverts in scenarios where borrowers or troves are invalid.
Run the following commands after applying the git diff:
forc test test_works_for_existing_trove --logs
-> runs the control test
forc test test_reverts_for_non_existing_trove --logs
-> run the test that fails
Apply the git patch below: