# SorStaking: incorrect reward calculation drained via repeated withdrawals

SorStaking's flawed reward calculation let an attacker deposit SOR, wait 14 days, then repeatedly withdraw 1 wei to drain ~8 ETH in rewards.

- Payout: Real-world hack
- Severity: high
- Program: SorStaking
- Credited: DeFiHackLabs
- Disclosed: 2025-01-04
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2025-01/sorraStaking.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20250104-sorrastaking
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:reward-distribution

**Target:** SorStaking staking contract
**Root cause:** Reward calculation incorrectly credits rewards per withdrawal or fails to update state properly, allowing repeated small withdrawals to claim disproportionate rewards.
**Steps:**
1. Acquire 122,868.87 SOR tokens (deal in PoC).
2. Approve SorStaking contract to spend SOR.
3. Call `deposit(122868871710593438486048, 0)` to stake all SOR with tier 0.
4. Warp time forward 14 days + 1 second to accrue rewards.
5. Loop 800 times calling `withdraw(1)` to claim rewards repeatedly.
6. Approve Uniswap router to spend remaining SOR.
7. Swap SOR for ETH via Uniswap V2 router in 7 iterations of 700,000 SOR each.
8. Profit ~8 ETH (4.8 + 2.4 + 0.8 ETH from multiple txs).
**How found:** Likely identified through code review that reward calculation did not properly account for partial withdrawals or updated reward debt incorrectly, allowing repeated claims.
**Exploitation:** Attacker staked a large amount of SOR, waited the lock period, then performed many tiny withdrawals (1 wei each) to exploit a reward calculation bug that overpaid rewards per withdrawal. The accumulated SOR rewards were swapped to ETH on Uniswap.
**Escalation:** Repeated withdrawals amplified the reward overpayment; multiple attack transactions netted 4.8, 2.4, and 0.8 ETH.
**Insight:** When auditing staking contracts, check if reward calculation uses a per-withdrawal multiplier or fails to update reward debt on partial withdrawals; test with tiny withdrawal amounts after lock period.
