# Attackers can use `reclaimContract()` to transfer assets in protocol to address(0)

reclaimContract() transfers premium+collateral to bulls[contractId], which is address(0) for unmatched fake orders, sending protocol tokens to the zero address.

- Payout: Contest reward
- Severity: high
- Program: Bullvbear
- Credited: Ruhum
- Disclosed: 2022-11-05
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2022-11-bullvbear-judging/issues/127
- Library page: https://bugbountylibrary.com/r/sherlock%3A2022-11-bullvbear%3AH-1
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** BvbProtocol.reclaimContract() order settlement contract
**Root cause:** reclaimContract() reads bull = bulls[contractId] without verifying the order was ever matched, so an unmatched order yields bull = address(0); tokens lacking a to!=0 check then transfer to the zero address.
**Steps:**
1. Craft a fake Order with attacker-chosen asset, premium+collateral>0, and expiry in the past
2. Ensure contractId (uint of hashOrder) is not in settledContracts or reclaimedContracts
3. Call `reclaimContract(fakeOrder)`; require checks pass since timestamp>expiry and flags unset
4. bull = bulls[contractId] = address(0); `IERC20(order.asset).safeTransfer(address(0), premium+collateral)` executes
5. If the token lacks a zero-address check, funds are permanently burned to address(0)
**How found:** Code review of reclaimContract(): noticed bull is derived from bulls[contractId] with no check that the order was matched, and that the transfer target could therefore be the zero address for arbitrary attacker-supplied orders.
**Exploitation:** Attacker submits a self-crafted expired order for an unmatched contractId; reclaimContract() passes all requires and transfers the protocol's held asset amount to address(0), permanently destroying funds.
**Insight:** When a function derives a recipient from a mapping keyed by a hash of user-supplied struct data, check whether that mapping entry is guaranteed populated; unmatched/unknown keys silently default to address(0) and become an attacker-controlled burn sink.
