Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Description
Brief / Intro
The Staking contract's withdrawal mechanism is vulnerable to a Denial-of-Service attack where a malicious actor can deposit numerous small ("dust") stakes to a victim's address, causing the _consumeUnlockedSharesOrRevert function to exceed the block gas limit during withdrawal attempts. This attack exploits the linear iteration over stake arrays in the share consumption logic.
Vulnerability Details
deposit allows anyone to deposit on behalf of another user. Each deposit creates a new entry in the stakes[to] array via stakes[to].push():
Staking.sol (snippet)
functiondeposit(uint256assets,addressto)publicvirtualreturns(uint256shares){if(assets >maxDeposit(to))_revert(0xb3c61a83);// `DepositMoreThanMax()`. shares =previewDeposit(assets);_deposit(msg.sender, to, assets, shares);}
As a result the userStakes array grows linearly with each deposit. The _consumeUnlockedSharesOrRevert function iterates over the entire array to find unlocked shares, which can cause the function to exceed the block gas limit:
Impact Details
Permanent locking of a victim's funds is possible: an attacker can spam many dust stakes to the victim's stake array (by depositing on behalf of them), causing withdrawals to run out of gas and revert.