The PriorityPool's merkle tree implementation is vulnerable to double spend attacks.
In the PriorityPool, the same merkleRoot and proof can be used to satisfy multiple simultaneous flows, enabling a user to both claim LSDs and the ability to withdraw simultaneously, if spent in different ways.
For example, the same merkle proof can be used to satisfy both a call to withdraw:
And simultaneously a call to unqueueTokens:
In both journeys, proof construction takes the exact same leaf shape:
This makes the same proof valid in both journeys, and consequently, they can be double spent.
It would be impossible to give someone a proof to permit them to only unqueue their tokens without inadvertently also allowing that same user to simultaneously withdraw a balance of these tokens too.
Manual Review
Prevent leaves from being double spent by ensuring that the proof additionally encodes the intended user journey (i.e. unqueue or withdraw) within the pool, instead of being applicable to multiple flows.
It does concern different variables. But using the same merkle inside 3 different functions is not a good practice. Nonces, separators and safety.
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.