# Non-existing revenue contract can be passed to claimRevenue to send all tokens to treasury

Unregistered revenueContract passed to claimRevenue defaults ownerSplit to 0, routing all push-payment revenue to treasury and starving lender escrow.

- Payout: Contest reward
- Severity: high
- Program: Debt DAO
- Credited: Lambda
- Disclosed: 2023-02-07
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-11-debtdao-findings/issues/119
- Library page: https://bugbountylibrary.com/r/c4%3A2022-11-debtdao%3AH-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** SpigotLib.claimRevenue / _claimRevenue (Solidity contract)
**Root cause:** claimRevenue never verifies revenueContract was registered; missing settings default claimFunction to 0 (push-payment branch) and ownerSplit to 0, so escrowedAmount = claimed*0/100 = 0 and full claimed amount goes to treasury.
**Steps:**
1. Identify a token whose revenue contract uses push payments so Spigot balance grows over time.
2. Call `spigot.claimRevenue(address(0), address(token), "")` with a non-existent revenueContract.
3. Observe claimFunction==0 triggers push-payment branch computing claimed = existingBalance - escrowed[token].
4. ownerSplit==0 makes escrowedAmount 0; entire claimed amount transfers to treasury, none to escrow.
5. Repeat each period to keep lender escrow empty regardless of configured split.
**How found:** Code reading of SpigotLib._claimRevenue: noticed the push-payment branch keyed on claimFunction==0 and ownerSplit read from settings without any registration check, implying default-zero settings silently misroute funds.
**Exploitation:** Borrower periodically calls claimRevenue with an arbitrary unregistered address and the push-payment token; each call sweeps all newly received revenue to the treasury, leaving escrow with zero so the lender never receives its configured share.
**Insight:** When a function branches on a mapping lookup (claimFunction==0) and later divides by another mapping value (ownerSplit), test what happens for unset keys: default-zero structs often silently select a fallback branch and zero out splits, turning a missing existence check into fund misrouting.
