# DOS of market operations with malicious offers

RubiconMarket offer() accepts zero-address owner/recipient, creating an unfillable best-price offer that reverts buyAllAmount/sellAllAmount and DoSes Position.sol.

- Payout: Contest reward
- Severity: high
- Program: Rubicon
- Credited: carrotsmuggler
- Disclosed: 2025-02-17
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-04-rubicon-findings/issues/644
- Library page: https://bugbountylibrary.com/r/c4%3A2023-04-rubicon%3AH-12
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** RubiconMarket.sol offer()/buyAllAmount/sellAllAmount and Position.sol
**Root cause:** offer() does not sanitize owner/recipient addresses, so an offer paying to address(0) is accepted and inserted at the head of the sorted _best linked list; filling it reverts on OZ ERC20 transfer-to-zero check, reverting the whole buyAllAmount loop.
**Steps:**
1. Call `offer(parseUnits("100"), testCoin, parseUnits("110",6), testStableCoin, address(0), address(0))` with a very good price so it becomes _best head.
2. Any `buyAllAmount`/`sellAllAmount` loop calls `getBestOffer()` and picks this offer first.
3. Filling it attempts ERC20 transfer to address(0), reverting with 'ERC20: transfer to the zero address'.
4. Whole transaction reverts; Position.sol (which only uses buyAllAmount/sellAllAmount) is bricked; _matcho also blocked from creating new offers.
**How found:** Code reading of buyAllAmount's while loop calling getBestOffer and the sorted linked list; noticed offer() lacks zero-address validation and OZ ERC20 reverts on transfer to zero, making the best-price offer unfillable.
**Exploitation:** Attacker posts a small-volume offer at an unbeatable price with owner and recipient set to address(0). It sits at the head of the sorted linked list; every buyAllAmount/sellAllAmount iteration hits it first and reverts, blocking market fills and Position unwinds, risking liquidation losses.
**Escalation:** Secondary impact: _matcho matches new offers against existing ones first, so the unfillable head also blocks creation of new orders.
**Insight:** In order-book/AMM loops that iterate best offers, an offer that reverts on fill (zero address, blacklisted recipient, reverting token) at the best price bricks the entire loop; check whether offer creation validates payout addresses and whether the fill loop has try/catch to skip bad offers.
