Open c4-bot-10 opened 6 months ago
0xRobocop marked the issue as duplicate of #180
OpenCoreCH changed the severity to QA (Quality Assurance)
Hi @OpenCoreCH,
thank you very much for reviewing this contest. While I understand your reasoning in the primary issue #180 I would like to add why in my opinion this issue fulfills a medium severity according to C4 judging criteria.
Also, I'd like to add that of the duplicates of #180 only this issue, #144 and #26 describe the same and correct issue. #161 mentions some invalid rounding issue.
While I understand your reasoning, the fact that the protocol does not work as intended alone is not a guarantee for a valid medium (see https://docs.code4rena.com/awarding/judging-criteria/supreme-court-decisions-fall-2023). For this issue, while it would definitely be annoying that this call fails, the issue does not show how this would impact users, their interaction with the protocol, or what the benefit of an attacker after performing this attack would be.
Lines of code
https://github.com/code-423n4/2024-02-hydradx/blob/main/HydraDX-node/pallets/omnipool/src/lib.rs#L1547
Vulnerability details
Bug Description
The HydraDX protocol includes the Omnipool AMM. It allows for the registration of single tokens through the Authority. When a token becomes compromised or worthless, an authority can also remove a token from the Omnipool using
remove_token()
.To be able to remove a token, the token has to fulfill 2 requirements.
First, the token has to be in the FROZEN state. This can easily be achieved by the Authority by setting the asset's tradable state using the function
set_asset_tradable_state()
.The second requirement is that all remaining shares of the asset have to be held by the protocol. Here is where the problem occurs. If only a single user does not withdraw all his shares, the
remove_token()
will always fail. This requires some loss on the user's behalf, as the market will probably stay frozen and his shares won't earn any interest and will be stuck until he stops the DOS. This might seem to deter attackers from abusing this, but in reality, an attacker would only need to keep 1 share inside the pool. For example, for the USDC used in the test, this would only cost him 1$ total, to keep an endless DOS on theremove_token()
functionality.Impact
The issue allows a malicious user to DOS the Omnipool's
removeToken()
functionality indefinitely at a cost of ~1$.Proof of Concept
The issue can be seen in the following testcase, where a user blocks the
removeToken()
functionality at the cost of ~1$The test can be added to the
pallets/omnipool/src/tests/remove_token.rs
file.Tools Used
Manual Review
Recommended Mitigation Steps
The issue can be mitigated by separating the token removal and liquidity withdrawals. A simple way to facilitate this would be to implement an escrow mechanism. This way when a token gets removed, all remaining liquidity would be transferred to an escrow where the holders can withdraw it.
Assessed type
DoS