# DOS any Staking contract with Arithmetic Overflow

Attacker reuses a shared MultiRewardStaking contract and adds 255 reward tokens, overflowing the uint8 loop index in accrueRewards and bricking all staking functions.

- Payout: Contest reward
- Severity: medium
- Program: Popcorn
- Credited: gjaldon
- Disclosed: 2023-09-07
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-01-popcorn-findings/issues/165
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-popcorn%3AM-32
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:dos

**Target:** MultiRewardStaking / VaultController (Solidity staking contract)
**Root cause:** accrueRewards iterates rewardTokens with a uint8 index; rewardTokens length is unbounded and any vault creator can attach arbitrary reward tokens to a shared staking contract, so 256 tokens overflow the index and every function using the modifier reverts.
**Steps:**
1. Deploy a legit vault; note its shared MultiRewardStaking address.
2. As attacker, deploy a new vault reusing that same staking contract via controller.deployVault.
3. Call controller.addStakingRewardsTokens with 255 new MockERC20 reward tokens targeting the attacker vault.
4. Any staking call (e.g. IMultiRewardStaking(staking).deposit) now reverts with arithmetic overflow, locking funds.
**How found:** Code reading: noticed accrueRewards uses uint8 loop index over an unbounded rewardTokens array, and that VaultController lets any creator attach arbitrary reward tokens to any previously deployed staking contract.
**Exploitation:** Attacker needs only a vault deployment reusing the victim's staking contract and permission to add reward tokens; adding 255 tokens pushes rewardTokens.length to 256, so the uint8 loop counter in accrueRewards overflows and all deposit/withdraw/transfer/claimRewards calls revert, freezing staked funds.
**Insight:** When a shared contract is reused across user-deployed instances, look for unbounded arrays iterated with narrow integer types (uint8/uint16) in modifiers that gate all state-changing functions; a length equal to the type's max+1 bricks the contract.
