Summary
When a user cancels a queued withdrawal via cancelQueuedWithdrawal, the function re-mints shares using previewDeposit(request.assets) at the current exchange rate rather than restoring the original number of shares that were burned.
Issue
If the share price changed during the cooldown period (due to receiveRewards donations or other activity), the user receives a different number of shares than originally burned:
- If price decreased: user gets more shares → profit at other stakers' expense
- If price increased: user gets fewer shares → loss for the canceller
This creates a free option for the canceller — they can monitor the price and only cancel when it's profitable.
Affected Code
WBERAStakerVault.sol#L248-L258:
uint256 assets = request.assets;
uint256 maxAssets = maxDeposit(msg.sender);
if (assets > maxAssets) {
revert ERC4626ExceededMaxDeposit(msg.sender, assets, maxAssets);
}
uint256 newSharesToMint = previewDeposit(assets); // ← uses current rate
reservedAssets -= assets;
_mint(msg.sender, newSharesToMint);
Recommended Fix
Re-mint the original number of shares that were burned at queue time:
- uint256 newSharesToMint = previewDeposit(assets);
+ uint256 newSharesToMint = request.shares;
This preserves the user's original position and prevents any exchange rate arbitrage.
Severity
Low — Requires price movement during cooldown period and the attacker bears token risk during the wait.
Summary
When a user cancels a queued withdrawal via
cancelQueuedWithdrawal, the function re-mints shares usingpreviewDeposit(request.assets)at the current exchange rate rather than restoring the original number of shares that were burned.Issue
If the share price changed during the cooldown period (due to
receiveRewardsdonations or other activity), the user receives a different number of shares than originally burned:This creates a free option for the canceller — they can monitor the price and only cancel when it's profitable.
Affected Code
WBERAStakerVault.sol#L248-L258:Recommended Fix
Re-mint the original number of shares that were burned at queue time:
This preserves the user's original position and prevents any exchange rate arbitrage.
Severity
Low — Requires price movement during cooldown period and the attacker bears token risk during the wait.