The PriorityPool contract exhibits inconsistent behaviour when processing deposits in a paused state. When the contract is paused, deposits that don't require queueing are partially processed, while deposits that do require queueing are fully reverted. This inconsistency could lead to unexpected behaviour and potential exploitation.
In the _deposit function of the PriorityPool contract, there's an inconsistency in how deposits are handled when the contract is paused:
The issue arises specifically in this section of the function:
When _shouldQueue is false:
The function processes the deposit up to the amount of queued withdrawals.
Any remaining amount is returned to the user.
The transaction does not revert, even though the contract is paused.
When _shouldQueue is true:
The function attempts to process the deposit up to the amount of queued withdrawals.
When trying to queue the remaining amount, it calls _requireNotPaused().
This causes the entire transaction to revert, undoing any processed withdrawals.
This inconsistency means that the paused state is only partially enforced, depending on the _shouldQueue parameter. This could lead to unexpected state changes even when the contract is supposed to be paused.
Likelihood of Exploitation:
High - The conditions required for this improper functioning are easily achievable. The inconsistent behaviour occurs in a common state (when the contract is paused) and can be triggered by standard user interactions (deposits with different queue preferences).
While user funds are not directly at risk, the protocol fails to function as intended:
Inconsistent enforcement of the paused state
Potential for unexpected partial deposits when paused
Violation of the expected behaviour of a paused contract
This discrepancy between intended and actual functionality could lead to user confusion and potentially undermine trust in the protocol's reliability, even if it doesn't directly threaten user assets.
Manual review
Enforce consistent behaviour:
Move the _requireNotPaused() check to the beginning of the _deposit function.
This ensures that no deposits of any kind can be processed when the contract is paused.
Alternative approach:
If the intention is to allow fulfilling queued withdrawals even when paused, create a separate function for this purpose that can be called even when paused.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.