# Users Can Bypass Emergency Restrictions on updateUserRewardState()

Emergency-state reward-update restriction on Paladin's HolyPaladinToken is bypassed by transferring tokens, letting users keep accruing rewards during emergency withdraw.

- Payout: Audit contest
- Severity: medium
- Program: Paladin
- Found by: leastwood
- Disclosed: 2022-05-10
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-03-paladin-findings/issues/94
- Library page: https://bugbountylibrary.com/r/c4%3A2022-03-paladin%3AM-13
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:business-logic vuln:reward-distribution

**Target:** HolyPaladinToken ERC20 reward accounting (_beforeTokenTransfer/_updateUserRewards)
**Root cause:** _beforeTokenTransfer() unconditionally calls _updateUserRewards() on from/to accounts without checking the emergency boolean, so transfers re-enable reward accrual that emergency state intends to freeze.
**Steps:**
1. Owner calls triggerEmergencyWithdraw(), setting emergency=true; stake/lock/unlock/kick and direct _updateUserRewards() calls now revert.
2. User holds locked tokens plus a small amount of unlocked tokens.
3. User transfers a small amount of unlocked tokens to their own account.
4. _beforeTokenTransfer() invokes _updateUserRewards() on from and to, updating reward state despite emergency.
5. User delays emergencyWithdraw() to keep accruing rewards and claim a larger share of allocated rewards.
**How found:** Code reading of emergency-state guards: noticed _updateUserRewards() is blocked directly but reachable indirectly via _beforeTokenTransfer() on any transfer, which lacks the emergency check.
**Exploitation:** Attacker self-transfers a tiny amount of unlocked tokens during emergency state to force _updateUserRewards() execution, continuing reward accrual and deferring emergencyWithdraw() to capture a higher proportion of allocated rewards.
**Insight:** When a protocol freezes a state-mutating function during emergencies, check every indirect caller of that function (hooks like _beforeTokenTransfer, callbacks, batch paths) for the same guard; a self-transfer of 1 wei is often enough to reach it.
