# ConvexMasterChef's deposit and withdraw can be reentered drawing all reward funds from the contract if reward token allows for transfer flow control

ConvexMasterChef deposit/withdraw transfer rewards before updating rewardDebt, letting a hook-capable reward token reenter and drain all reward funds.

- Payout: Contest reward
- Severity: medium
- Program: Aura Finance
- Credited: hyh
- Disclosed: 2022-07-26
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-05-aura-findings/issues/313
- Library page: https://bugbountylibrary.com/r/c4%3A2022-05-aura%3AM-17
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:reentrancy

**Target:** ConvexMasterChef staking contract (deposit/withdraw)
**Root cause:** deposit() and withdraw() call safeRewardTransfer before updating user.amount and user.rewardDebt, so reward accounting is stale during the external transfer.
**Steps:**
1. Reward token has transfer hooks (e.g. ERC777 or _beforeTokenTransfer) or is upgradeable to add them.
2. User stakes so user.amount > 0 and accrues pending rewards.
3. Call `deposit(_pid, tinyAmount)` or `withdraw(_pid, tinyAmount)`; safeRewardTransfer(msg.sender, pending) fires.
4. In the token transfer hook, reenter deposit()/withdraw() with tiny _amount; rewardDebt is still stale so pending is recomputed and paid again.
5. Repeat reentrancy until contract reward token balance is drained.
**How found:** Code reading of deposit/withdraw ordering: noticed safeRewardTransfer executes before user.amount/rewardDebt updates, then reasoned about reward tokens with transfer flow control (ERC777/hooks) enabling reentry.
**Exploitation:** Attacker needs the reward token to grant control during transfer (hook or upgrade). On each reentrant call the stale rewardDebt causes the same pending reward to be paid repeatedly, extracting the contract's entire reward token holdings.
**Insight:** In MasterChef-style contracts, check whether the reward token itself can call back during transfer (ERC777, hooks, upgradeable) — late rewardDebt updates then become a drain primitive even without a malicious LP token.
