The deposit() function tracks staked assets for the receiver parameter but mints shares to msg.sender, creating a dangerous mismatch that allows front-running and gaming of the system.
Normal behavior in ERC4626 vaults expects consistent handling where if shares are minted to an address, that same address should be tracked for deposits and withdrawals.
The current implementation assigns stakedAsset[receiver] but calls _mint(msg.sender, shares), creating a split where one address holds the shares but another address is tracked as the depositor. This breaks the tracking system and enables manipulation.
Likelihood:
Function interface explicitly allows receiver != msg.sender with no validation preventing this
Attackers can call deposit with arbitrary receiver addresses
Common pattern in DeFi to have separate receiver parameters, making this appear intentional
Impact:
Alice can call deposit(1000, bob) - Bob's stakedAsset increases but Alice receives the shares
When Bob checks joinEvent(), it passes because stakedAsset[bob] > 0
Bob can join event but has zero shares - receives nothing on winning
Alice holds shares without being tracked as participant - can potentially bypass restrictions
In cancelParticipation(), Bob gets refund based on stakedAsset[bob] but Alice holds the shares
Creates accounting mismatch between share holders and stake trackers
Enables griefing attacks where attacker deposits "for" victims who then can't claim
Breaks the fundamental assumption that depositor = share holder
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.