The withdraw function in the StakingPool contract contains inefficiencies in its liquidity withdrawal process and a potential discrepancy between burned tokens and actual withdrawals.
The withdraw function in StakingPool.sol (lines 142-165) has two main issues:
Inefficient Liquidity Check: The function attempts to withdraw liquidity before checking if the contract has sufficient balance, potentially wasting gas on unnecessary operations.
Token Burning Discrepancy: The function burns the full requested amount of tokens from the user's account before ensuring that the full amount can be withdrawn, potentially leading to a mismatch between burned tokens and actual withdrawals.
The function first calculates the amount to withdraw, then checks the contract's balance. If the withdrawal amount exceeds the balance, it calls _withdrawLiquidity to attempt to cover the difference. However, it doesn't check if this operation was successful before proceeding.
After these operations, it performs a require check to ensure sufficient liquidity, but this check comes too late in the process. If it fails, all previous operations (including the potentially expensive _withdrawLiquidity call) will be reverted, wasting gas.
Finally, the function burns the full requested amount from the user's account and updates totalStaked, regardless of whether the full amount could actually be withdrawn.
This implementation could lead to several issues:
Gas Wastage: Attempting to withdraw liquidity before checking the balance can lead to unnecessary gas consumption, especially if the withdrawal ultimately fails.
Incorrect Token Burning: Users might have more tokens burned than they actually receive if the contract can't fulfill the full withdrawal amount, leading to a loss of user funds.
Inaccurate Total Staked Tracking: The totalStaked variable might be reduced by more than the actual withdrawn amount, leading to accounting discrepancies.
Potential for Imaginary Withdrawals: The receiver might receive less than the burned amount, or in extreme cases, no tokens at all while still having their staked balance reduced.
Code Snippet
To address these issues, consider the following changes:
Check the contract's balance before attempting to withdraw liquidity:
Only burn and transfer the amount that can actually be withdrawn:
You can also Consider returning the actual withdrawn amount to the caller, so they can handle partial withdrawals appropriately.
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.