The deposit() function allows users to deposit assets multiple times. When a user deposits, the contract records the staked amount in the stakedAsset mapping for the receiver address. However, the implementation uses assignment instead of accumulation, which means each subsequent deposit overwrites the previous stake amount rather than adding to it.Explain the specific issue or problem in one or more sentences.
`stakedAsset[receiver] = stakeAsset;` overwrites any existing value instead of accumulating deposits. This means if a user deposits 5 ETH and then deposits 3 ETH again, only the 3 ETH is recorded. When the user calls `cancelParticipation()`, they only receive the last deposit amount back, resulting in permanent loss of the previous deposits.
Likelihood:
Users may deposit multiple times during the deposit window before the event starts
The contract has no mechanism to prevent or warn about multiple deposits
Users expecting their deposits to accumulate will lose funds
Impact:
Permanent loss of funds for users who deposit multiple times
Users only receive refund for the last deposit amount when cancelling
No way to recover overwritten deposit amounts
The PoC test below proves that a user who makes two deposits and then cancels their bet only gets refunded for the second deposit.
Either make the bets accumulate or allow only one deposit per user. However, please note that simply changing the assignment to accumulation (`+=`) is not sufficient, as it would introduce another bug: if a user calls `joinEvent()`, transfers shares away, calls `cancelParticipation()`, and then repeats this process, the `usersAddress` array will accumulate multiple entries for the same user while `userSharesToCountry` accumulates. This would lead to `totalWinnerShares` being inflated when `_getWinnerShares()` iterates over `usersAddress` entries, allowing the malicious user to get a larger prize than they should if they win the be. The fix must also ensure proper cleanup in `cancelParticipation()`.
Vault tracks only a single deposit slot per user and overwrites it on every call instead of accumulating the total.
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.