# Bizness Locker: reentrancy in splitLock drains locked tokens

Reentrancy in Bizness Locker's splitLock lets attacker re-enter withdrawLock during split, draining the original lock while retaining the split lock's tokens.

- Payout: Real-world hack
- Severity: high
- Program: Bizness
- Credited: DeFiHackLabs
- Disclosed: 2024-12-27
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2024-12/Bizness_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20241227-bizness
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:chained vuln:reentrancy

**Target:** Locker contract splitLock/withdrawLock on Base
**Root cause:** splitLock sends ETH to the caller before finalizing lock state, allowing reentrancy into withdrawLock which marks the original lock withdrawn while the split lock still holds the amount.
**Steps:**
1. Fork Base at block 24282214-1; attacker holds lockId 11 via transferLock
2. Call `splitLock{value:0.011 ether}(lockId, lockBefore.amount - 1, 1735353747)`
3. In receive(), re-enter `withdrawLock(lockId)` to withdraw the original full lock
4. splitLock completes, creating newSplitId holding amount-1 tokens
5. Attacker keeps both withdrawn funds and the new split lock balance
**Exploitation:** Attacker triggers splitLock with a small ETH value; the contract's ETH refund to the caller invokes receive(), which re-enters withdrawLock on the original lockId, withdrawing the full amount before splitLock finalizes. The split lock is still created with amount-1 tokens, netting the attacker the original lock's value plus the split lock.
**Insight:** Locker-style split functions that refund ETH mid-execution are reentrancy candidates: check whether the original lock is marked withdrawn before the split lock is persisted, and whether receive() can re-enter withdraw on the parent id.
