# [ConcurRewardPool] Possible reentrancy when claiming rewards

ConcurRewardPool.claimRewards transfers ERC777 reward tokens before zeroing balances, letting a malicious tokensToSend callback reenter and drain rewards.

- Payout: Audit contest
- Severity: medium
- Program: Concur Finance
- Found by: ShadowyNoobDev
- Disclosed: 2022-05-24
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-02-concur-findings/issues/86
- Library page: https://bugbountylibrary.com/r/c4%3A2022-02-concur%3AM-21
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:reentrancy

**Target:** ConcurRewardPool.claimRewards reward distribution contract
**Root cause:** claimRewards transfers reward tokens before setting the claimant's balance to zero, so an ERC777 tokensToSend hook can reenter claimRewards while the balance is still non-zero.
**Steps:**
1. Deploy attacker contract with an ERC-1820-registered tokensToSend() hook.
2. Accrue claimable pBTC rewards for the attacker contract via normal Concur flow.
3. Call `ConcurRewardPool.claimRewards()`; pBTC transfer() invokes `_callTokensToSend` -> `IERC777Sender.tokensToSend`.
4. Inside tokensToSend, re-call `claimRewards()` n-1 times before the original balance is zeroed, draining pBTC rewards.
**How found:** Code reading of claimRewards ordering: tokens transferred before balances set to 0, combined with knowledge that pBTC (ERC777, on Convex) triggers tokensToSend callbacks on transfer, analogous to the imBTC/Uniswap v1 hack.
**Exploitation:** Attacker registers a malicious ERC777 tokensToSend callback via ERC-1820, then triggers claimRewards; each pBTC transfer reenters claimRewards before the balance is reset, repeating until the pool's pBTC rewards are drained.
**Insight:** When a reward pool pays arbitrary tokens, check whether any supported token is ERC777/ERC677/hook-bearing; transfer-before-state-update ordering becomes exploitable even without native ETH callbacks.
