A critical bug has been identified in the withdraw function of the PriorityPool smart contract, specifically related to the validation logic that compares a user's Merkle tree index with the size of the Merkle tree (merkleTreeSize). This issue causes incorrect rejection of valid users during withdrawal attempts. The bug stems from an incorrect validation condition that triggers a revert when a user's index is smaller than the tree size. A correct validation procedure is observed in the unqueueTokens function, but this logic is improperly applied in withdraw, creating a security vulnerability that could prevent users from withdrawing their tokens. According to the project documentation, "Yes, you can withdraw your LINK from the Priority Pool at any time", making the bug a violation of intended contract functionality.
The core issue lies in the validation logic of the withdraw function. Here’s the problematic code snippet:
In this logic, if the user’s accountIndexes[account] is less than the merkleTreeSize, the transaction is reverted with an InvalidProof error. However, according to the Merkle Tree design and the system's documentation, if a user's index is less than the tree size, it signifies that the user is part of the current valid Merkle tree and thus their tokens should be withdrawable.
The correct logic can be seen in the unqueueTokens function:
In this function, the same comparison between accountIndexes[account] and merkleTreeSize is performed, but instead of directly reverting, the function goes on to verify the Merkle proof. Only if the proof is invalid does it revert the transaction. This is the correct approach, as it ensures that users who are part of the current tree can withdraw their tokens, provided their Merkle proof is valid.
This vulnerability results in a denial of service for legitimate users. Any user whose index is less than the merkleTreeSize will incorrectly be blocked from withdrawing their tokens from the pool. Given that accountIndexes[account] < merkleTreeSize should indicate that the user is part of the valid Merkle tree, the current logic incorrectly prevents valid withdrawals.
Manually
Replace the current incorrect comparison logic with the correct validation used in the unqueueTokens function.
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.