The _withdraw function in the PriorityPool contract lacks a crucial step: swapping liquid staking tokens (LSTs) for underlying asset tokens during withdrawals. This omission, likely due to an incomplete implementation of the withdrawal logic, allows users to withdraw LSTs instead of the expected underlying tokens. The bug leads to severe consequences including accounting discrepancies, potential loss of funds, and a fundamentally broken withdrawal mechanism.
The vulnerability is located in the _withdraw function:
Root cause: The function lacks a step to swap LSTs for underlying tokens before transferring them to the user or queueing the withdrawal.
Exploit path:
A user initiates a withdrawal through the withdraw function, which calls _withdraw internally.
The function processes queued tokens if available.
For any remaining withdrawal amount, instead of swapping LSTs for underlying tokens, it either:
a) Queues the withdrawal without converting tokens, or
b) Implicitly allows the transfer of LSTs instead of underlying tokens.
The function updates internal accounting as if a proper withdrawal of underlying tokens occurred.
Users receive LSTs instead of underlying tokens, violating the expected behavior of the withdrawal process.
Significant accounting discrepancies arise between the contract state and actual token balances.
Potential financial losses for users who are unaware they're receiving LSTs instead of underlying tokens.
The withdrawal mechanism becomes effectively non-functional for its intended purpose.
Inaccurate liquidity reporting, potentially causing unnecessary transaction reverts.
Withdrawals may be unnecessarily queued in the withdrawal pool.
totalQueued is reduced incorrectly, as LSTs are not actually swapped for underlying tokens.
depositsSinceLastUpdate and sharesSinceLastUpdate are increased based on LST amounts rather than underlying token movements, leading to inflated figures.
The withdrawal pool may accumulate unnecessary or incorrectly denominated withdrawal requests.
Users' balances in the contract remain unchanged in terms of underlying tokens, while they receive LSTs, creating a mismatch between expected and actual token holdings.
Manual code review
Implement token swapping mechanism:
Add a function to swap LSTs for underlying tokens within the _withdraw function.
Add proper checks and balances:
Implement checks to ensure that the correct amount of underlying tokens is received after swapping.
Update accounting accurately:
Ensure that depositsSinceLastUpdate and sharesSinceLastUpdate are updated based on the actual underlying tokens withdrawn, not the LST amount.
Implement slippage protection:
Add a parameter for minimum expected underlying tokens to protect users from excessive slippage during swaps.
Add events for transparency:
Emit events that clearly show the amount of LSTs swapped and underlying tokens received.
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.