# cannot forward extra rewards from both OCY_Convex to OCT_YDL.

OCY_Convex lockers treat Convex VirtualBalanceRewardPool contracts as ERC20 tokens, so extra rewards can never be claimed or forwarded to OCT_YDL.

- Payout: Contest reward
- Severity: high
- Program: Zivoe
- Credited: 0xpiken
- Disclosed: 2024-03-19
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2024-03-zivoe-judging/issues/479
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-03-zivoe%3AH-7
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:reward-distribution

**Target:** OCY_Convex_A/B/C locker contracts (Solidity)
**Root cause:** extraRewards(i) returns a VirtualBalanceRewardPool contract address, but the code calls balanceOf and safeTransfer on that address as if it were the reward ERC20 token, instead of on rewardToken().token().
**Steps:**
1. Call extraRewardsLength() on the Convex BaseRewardPool to get the number of child reward contracts.
2. For each i, call extraRewards(i) to get the VirtualBalanceRewardPool address.
3. Observe the code calls IBaseRewardPool(rewardContract).rewardToken().balanceOf(address(this)) and IERC20(rewardContract).safeTransfer(OCT_YDL, rewardAmount).
4. balanceOf is queried on the reward token but safeTransfer is called on the VirtualBalanceRewardPool contract, which is not an ERC20, so the transfer reverts or sends nothing.
5. Extra rewards accumulate in the locker and are never forwarded to OCT_YDL.
**How found:** Read the Convex docs stating extraRewards entries are VirtualBalanceRewardPool contracts, then compared against the locker code that treats rewardContract as an ERC20 token.
**Insight:** When integrating with a rewards aggregator, verify what each registry getter actually returns (contract vs token) and confirm balanceOf and transfer are called on the same reward token address, not the pool contract.
