Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
Detail
A critical vulnerability in StakeV2's reward distribution mechanism allows manipulation of accumulatedDeptRewardsYeet() through stake/unstake patterns, leading to protocol insolvency and permanent loss of user funds. The issue creates a "bank run" scenario where early unstakers get paid using other users' funds, ultimately leaving late unstakers with total loss of principal.
Vulnerability Details
Core Issue
function accumulatedDeptRewardsYeet() public view returns (uint256) {
return stakingToken.balanceOf(address(this)) - totalSupply;
}
The function fails to account for pending unstakes, creating a desynchronization between balanceOf and totalSupply
Technical Flow
Note: I used eth but in this context eth means yeet.
Initial State:
// Three users stake 100 ETH each
Alice stakes: 100 ETH
Bob stakes: 100 ETH
Victim stakes: 100 ETH
Contract balance: 300 ETH
totalSupply: 300 ETH
Attack Pattern:
// Victim starts unstake
victim.startUnstake(100 ETH);
// since startUnstake reduces totalsupply by unstake amount(100) immediately
// State: balance = 300 ETH, totalSupply = 200 ETH
// Creates fake rewards: 100 ETH
// Protocol distributes "rewards"
executeRewardDistributionYeet(100 ETH)
// Transfers victim's pending unstake tokens
// Contract balance: 200 ETH
Cascading Insolvency:
// Victim unstakes using Alice's tokens
victim.unstake(0) // Gets 100 ETH
// Balance: 100 ETH
// Alice unstakes using Bob's tokens
alice.unstake(0) // Gets 100 ETH
// Balance: 0 ETH
// Bob attempts unstake
bob.unstake(0) // FAILS - No funds left
In this case we have two victims
Bob : late/last unstaker whose unstake failed due to insufficient contract balance.
Victim : whose stake was incorrectly used as reward due to the contracts failure to account for pending unstakes during accumulatedDeptRewardsYeet()
Impact Details
Protocol Insolvency:
Contract becomes unable to meet staking obligations
Each reward distribution reduces available funds
Creates unsustainable "first to withdraw" scenario