# Lost Rewards in MultiRewardStaking Upon Third-Party Withdraw

MultiRewardStaking._withdraw accrues rewards on caller and receiver but not owner, so third-party withdrawals silently forfeit the owner's accrued staking rewards.

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

**Target:** MultiRewardStaking ERC4626 vault contract
**Root cause:** _withdraw calls _accrueRewards on caller and receiver but never on owner, so the owner's reward debt is not settled before their shares are burned.
**Steps:**
1. Deploy MultiRewardStaking with a reward token (0.1/sec).
2. Alice deposits 1 ether via `staking.deposit(1 ether)`.
3. Advance time 10s so Alice accrues rewards.
4. Alice calls `staking.approve(bob, 1 ether)`.
5. Bob calls `staking.withdraw(1 ether, bob, alice)` — withdraws to himself from Alice.
6. Alice's balance is 0; `claimRewards(alice, ...)` reverts with ZeroRewards; Bob's claim also reverts.
**How found:** Noticed the inherited ERC4626 `withdraw(uint256,address,address)` was never overridden and that `_withdraw` accrues on caller/receiver but omits owner; confirmed by writing a Foundry test showing both parties end with zero claimable rewards.
**Exploitation:** Any approved spender or integrator using the standard ERC4626 `withdraw(assets, receiver, owner)` signature causes the owner's unaccrued rewards to be lost permanently; no attacker gain, victim loses rewards.
**Insight:** When a contract inherits ERC4626 and overrides `_withdraw`, check every address parameter (caller, receiver, owner) is passed to reward-accrual hooks — the owner is the one whose shares are burned and is easy to omit.
