# Reenterancy in _sendSherRewardsToOwner()

Sherlock's _sendSherRewardsToOwner deletes sherRewards_ after safeTransfer, letting a reentrant token drain the contract's SHER balance via ownerRestake.

- Payout: Audit contest
- Severity: medium
- Program: Sherlock
- Found by: kirk-baird
- Disclosed: 2022-05-17
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-01-sherlock-findings/issues/60
- Library page: https://bugbountylibrary.com/r/c4%3A2022-01-sherlock%3AM-04
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:reentrancy

**Target:** Sherlock.sol staking/reward contract (_sendSherRewardsToOwner via ownerRestake)
**Root cause:** sherRewards_[_id] is deleted after the external sher.safeTransfer() call, so a reentrant call still sees the original reward balance and transfers again.
**Steps:**
1. Deploy attack contract implementing a token callback hook on transfer
2. Call `initialStake()` with the smallest `period`
3. Wait `period` time to elapse
4. Call `ownerRestake()`; on reentry into `_sendSherRewardsToOwner` via `sher.safeTransfer` recursively call `ownerRestake()` until contract SHER balance is 0 or below reward amount
5. Unwind the reentrancy loop
**How found:** Code reading of _sendSherRewardsToOwner spotted state deletion after the external safeTransfer call, then traced the internal function to the external ownerRestake entrypoint to confirm reachability.
**Exploitation:** Attacker needs control of execution during sher.safeTransfer (e.g. ERC777-style hook). Each reentrant ownerRestake re-reads the undeleted sherRewards_[_id] and re-sends the same reward, recursively draining the contract's SHER balance.
**Insight:** When auditing reward-claim internals, trace every internal function that deletes a mapping to its external caller; deletion-after-transfer is exploitable whenever the payout token can invoke a hook, so check the token's transfer implementation for callbacks.
