The withdraw function in the VaultDepositController contract can withdraw and transfer more tokens than requested by the user under certain conditions. This can lead to unexpected token distributions and accounting inaccuracies.
The issue can be found in the withdraw function of the VaultDepositController contract.
https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/linkStaking/base/VaultControllerStrategy.sol#L135-L140
When the remaining balance in a vault after the requested withdrawal would be less than minDeposits, the function withdraws the entire vault balance instead of the requested amount.
if you take make a scenario with the following initial conditions:
Vault deposit: 1000 tokens
Minimum deposit (minDeposits): 100 tokens
User requests withdrawal: 800 tokens
Mathematical breakdown:
Requested withdrawal: 800 tokens
Remaining balance if request fulfilled: 1000 - 800 = 200 tokens
Condition check: 200 > 0 && 200 < 100 (minDeposits)
Actual withdrawal: 1000 tokens (entire vault balance)
issue to look at
Tokens over-withdrawn: 1000 - 800 = 200 tokens
Percentage of excess withdrawal: (200 / 800) * 100 = 25%
Impact on the contract:
totalUnbonded: Reduced by 1000 instead of 800 (25% more reduction)
totalDeposits: Reduced by 1000 instead of 800 (25% more reduction)
totalPrincipalDeposits: Reduced by 1000 instead of 800 (25% more reduction)
if this issue pile up it can compound over multiple withdrawals, potentially leading to significant accounting errors and unexpected token distributions.
Manual
Implement a cap on the withdrawal amount:
Update accounting based on actual withdrawn amount:
Add a check to ensure withdrawal doesn't exceed requested amount:
If the behavior is intentional, rename the function and add clear documentation:
Add events for transparency:
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.