-
Notifications
You must be signed in to change notification settings - Fork 4
panprog - Some actions are allowed on partyB when corresponding partyA is liquidated allowing to steal all protocol funds #189
Comments
Comment from senior watson: Point 1 - As per the impact of the report, it mentioned the following: All protocol funds can be stolen if a user can control partyA, partyB and liquidator. Since partyB and liquidator roles are supposed to be easy to get, this means that most users are able to easily steal all protocol funds. The PartyB has to be vetted and whitelisted by protocol. The liquidator role also needs to be granted by the protocol. Only PartyA is public. It is challenging for an attacker to gain control of all three (3) roles in order to carry out the attack mentioned in the report. Thus, it does not meet the requirement of a high-risk rating |
Escalate This should be high, not medium.
As described above, both liquidator and partyB roles will be easy to get, so the scenario described is easy to achieve and the impact (all protocol funds stolen) makes it possible to ignore all possible deposits required to obtain these roles. As such, this should be high. |
You've created a valid escalation! To remove the escalation from consideration: Delete your comment. You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final. |
Escalate To carry out the attack mentioned in the report, the malicious user needs to gain control of all three (3) roles, which are PartyA, PartyB, and Liquidator roles, to carry out the attack. There are several measures present within the protocol that make such an event unlikely. PartyB (Hedger) and Liquidator roles are in fact not easy to obtain from the protocol, and they cannot be attained without explicit authorization from the protocol team. It will only be considered easy to obtain if they are permissionless, where anyone/anon could register to become a PartyB or Liquidator without being reviewed/vetted by the protocol team. PartyB and Liquidator roles must be explicitly granted by the protocol team via the In the current system, to become a PartyB, the Hedgers must be known entities such as market makers with a reputation and identifiable founders, etc, and not open to the general public. Those hedgers/entities have a lot at stake if they engage in malicious actions, which include facing legal consequences. The liquidator role is also not open to the general public, and the protocol would vet/review them before granting this role. Approved Liquidators are further required to lock in a certain amount of money, serving as a guarantee against any potential system sabotage. Lastly, it's worth noting that in a real-world context, PartyB and Liquidator roles are typically held by distinct entities. Hence, some degree of collusion - another layer of complexity - would be necessary for the attack to be successful. Given the controls in place and the several preconditions required for such an issue to occur, this issue should be considered of Medium severity. |
You've created a valid escalation! To remove the escalation from consideration: Delete your comment. You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final. |
I would have to agree with senior watson's escalation Consider that in the contest read me https://audits.sherlock.xyz/contests/85
TRUSTED
TRUSTED and
needs to be granted by the protocol, recommend consider this issue as a valid medium |
Fixed code PR link: |
Result: |
Escalations have been resolved successfully! Escalation status:
|
panprog
high
Some actions are allowed on partyB when corresponding partyA is liquidated allowing to steal all protocol funds
Summary
deallocateForPartyB
function doesn't check if partyA is liquidated, allowing partyB to deallocate funds when partyA liquidation process is not finished:https://github.com/sherlock-audit/2023-06-symmetrical/blob/main/symmio-core/contracts/facets/Account/AccountFacet.sol#L84-L91
transferAllocation
function doesn't check if partyA is liquidated either:https://github.com/sherlock-audit/2023-06-symmetrical/blob/main/symmio-core/contracts/facets/Account/AccountFacetImpl.sol#L71-L106
Either of these functions allows to deallocate (or transfer, then deallocate) funds for partyB when partyA liquidation is not yet finished. Coupled with the ability for liquidator to choose which partyA positions to liquidate, this allows to steal all protocol funds.
Vulnerability Detail
Liquidating partyA is a multi-step process. First,
liquidatePartyA
is called to mark the start of liquidation process. Then, liquidator has to set symbol prices, liquidate pending quotes and finally callliquidatePositionsPartyA
(possibly multiple times) with liquidated positions. Each position, which is liquidated in theliquidatePositionsPartyA
function increasesallocatedBalance
of partyB if the position is in a loss for partyA (profit for partyB).The bug reported here allows for partyB to deallocate this increased
allocatedBalance
while partyA liquidation is still in process. The scenario to exploit this bug is as following:liquidatePartyA
andsetSymbolsPrice
(there is no bad debt, because 1 position is in a big loss, the other position in a big profit, but their sum is in a small loss, which is covered by allocatd balance)singleUpnlSig
for partyB at this time (partyB is in a small profit)liquidatePositionsPartyA
with id of only the position which is in a loss for partyA, profit for partyB. This call increases partyB allocated balance by a very high profit of the position. Moreover, this action doesn't change partyB's nonce, so previous partyB signature is still valid.deallocateForPartyB
, deallocating inflated balance (which can easily be higher than total protocol deposited funds).The other instances where there is no check if party is liquidated:
requestToClosePosition
(it checks if quote is liquidated, but doesn't check for neither partyA nor partyB liquidation status)fillCloseRequest
(same asrequestToClosePosition
)deallocate
checks for partyA liquidation status, but can't check for partyB liquidation status, because there can be multiple partyB's. This is reported as a separate bug, because the core problem (muon app signing incorrect upnl) and solution for that one is different.Impact
All protocol funds can be stolen if a user can control partyA, partyB and liquidator. Since partyB and liquidator roles are supposed to be easy to get, this means that most users are able to easily steal all protocol funds.
Code Snippet
Add this to any test, for example to
ClosePosition.behavior.ts
.Tool used
Manual Review
Recommendation
Add require's (or modifiers) to check that neither partyA nor partyB of the quote are liquidated in the following functions:
deallocateForPartyB
transferAllocation
requestToClosePosition
fillCloseRequest
The text was updated successfully, but these errors were encountered: