#41456 [SC-Critical] `executeRewardDistributionYeet` will count user withdraws as rewards
Was this helpful?
Was this helpful?
Submitted on Mar 15th 2025 at 13:46:21 UTC by @Pyro for
Report ID: #41456
Report Type: Smart Contract
Report severity: Critical
Target: https://github.com/immunefi-team/audit-comp-yeet/blob/main/src/StakeV2.sol
Impacts:
Protocol insolvency
Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Smart contract unable to operate due to lack of token funds
executeRewardDistributionYeet
will count user withdraws as rewards due to the way we calculate the rewards inside accumulatedDeptRewardsYeet
accumulatedDeptRewardsYeet
calculates the rewards generated by removing totalSupply
from stakingToken.balanceOf(address(this))
Where that difference is used inside executeRewardDistributionYeet
as generated rewards, which are swapped for vault shares.
However accumulatedDeptRewardsYeet
forgets to consider the fact that startUnstake
keeps the staking tokens inside the contract, but lowers totalSupply
by unStakeAmount
as it sets that amount for a vest.
In short all user withdraws will be counted by the contract as rewards, meaning that if swapped these withdraws will not be refundable, or even worse - they would be taken from the users that didn't appoint a withdraw, making the contract insolvent.
Contract is insolvent due to it counting all pending withdraws as rewards and swapping them in a different token.
none are needed
10 users deposit, each with 100 tokens
1 schedules a withdraw for 100 tokens
Admin distributes rewards (these 100 tokens are counted towards the rewards)
User withdraws his 100 tokens
step 3 and 4 both costed 100 tokens, meaning the contract has 800 actual tokens and 900 deposited balances, making it insolvent.