# findNewOwner edgecase

findNewOwner's loop-counter check misclassifies a valid owner found on the final iteration as invalid, deleting them without ownership and letting an attacker rent cheaply.

- Payout: Audit contest
- Severity: high
- Program: Reality Cards
- Found by: gpersoon
- Disclosed: 2021-09-21
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2021-08-realitycards-findings/issues/27
- Library page: https://bugbountylibrary.com/r/c4%3A2021-08-realitycards%3AH-01
- Tags: area:web3 domain:web3 impact:funds-loss impact:integrity kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** RCOrderbook.findNewOwner orderbook loop (Solidity)
**Root cause:** The loop terminates on `_loopCounter < maxDeletions`, then uses `_loopCounter != maxDeletions` to decide completion; a valid owner found exactly on the last allowed iteration is indistinguishable from hitting the limit, so it is treated as invalid and saved for retry.
**Steps:**
1. Read `findNewOwner` in RCOrderbook.sol: do/while removes bids while foreclosed and `_loopCounter < maxDeletions`.
2. Observe the post-loop check `if (_loopCounter != maxDeletions)` decides whether a new owner was found.
3. Set `maxDeletions==1` (or reason generally): a valid owner found on the final iteration makes `_loopCounter == maxDeletions`, so the else branch saves the old owner instead of assigning the found one.
4. On the next rent collection, the previously-found valid owner is deleted immediately without receiving ownership.
**How found:** Code reading of the loop termination condition and the post-loop completion check; noticed the boundary case where processing finishes exactly when `_loopCounter == maxDeletions`, clearest with `maxDeletions==1`.
**Exploitation:** Attacker (Mal) uses Sybil accounts to place `maxDeletions - 1` minimum-duration bids, waits `(maxDeletions-1)*minimumRentalDuration` for them to expire, then bids low (e.g. $11 vs Alice's $100). The triggered rent collection runs findNewOwner; Alice is found on the final iteration but treated as invalid, so no ownership change/event occurs. UI still shows Alice as owner, deterring outbidders, while Mal accrues time at the cheap rate. Next collection deletes Alice without ownership.
**Escalation:** Sybil bids to fill the deletion budget so the legitimate high bidder lands exactly on the final loop iteration, enabling cheap rental and misleading UI state.
**Insight:** When a loop uses a counter both as a bound and as a completion signal, the boundary iteration is ambiguous; check whether 'found on last iteration' is conflated with 'hit the limit' — sponsors confirmed it generalizes to any maxDeletions, not just 1.

