Collateral cannot be withdrawn from trove once yang is suspended #48
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
edited-by-warden
M-07
primary issue
Highest quality submission among a set of duplicates
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2024-01-opus/blob/4720e9481a4fb20f4ab4140f9cc391a23ede3817/src/core/sentinel.cairo#L159
Vulnerability details
Impact
Once a yang (collateral asset) is suspended on Opus, the following holds true according to the documentation:
Therefore, a user will naturally deposit healthier collateral to their trove to maintain its threshold, while withdrawing the unhealthy/suspended collateral as it loses value on Opus, effectively replacing the collateral.
However, this is not possible because the underlying assets of a yang are immediately frozen once suspended. It's clear from the documentation that no more deposits of suspended collateral can be made, but this accidentally also affects the withdrawals.
The abbot::withdraw(...) method calls sentinel::convert_to_yang(...) which in turn calls sentinel::assert_can_enter(...):
One can see that the assertion will be triggered once the suspension status is
Temporary
orPermanent
.As a consequence, a yang's underlying assets are frozen once suspended:
Temporary
, the admin can unsuspend the yang to make it withdrawable again.However, this also stops its threshold decrease and makes it depositable again, which eliminates the incentives to withdraw in the first place. This essentially breaks the suspension mechanism.
Permanent
, the assets are permanently locked from withdrawal.Nevertheless, there is a workaround by closing the trove, which requires all the yin (debt) to be repaid and unnecessarily withdraws all other yangs (collateral assets) of the trove too. Therefore this is not a viable solution for the present issue.
Proof of Concept
The following PoC demonstrates that a yang's underlying assets cannot be withdrawn once suspended.
Add the test case below to
src/tests/abbot/test_abbot.cairo
and run it withsnforge test test_withdraw_suspended_fail
.Tools Used
Manual review
Recommended Mitigation Steps
Replace the accidental
assert_can_enter(..)
check with those that are really necessary at this point:Assessed type
Invalid Validation
The text was updated successfully, but these errors were encountered: