# RubiconRouter: Offers created through offerWithETH() can be cancelled by anyone

RubiconRouter.offerWithETH sets the router as offer owner, so anyone can call cancelForETH to cancel the offer and steal the deposited ETH.

- Payout: Contest reward
- Severity: high
- Program: Rubicon
- Credited: cccz
- Disclosed: 2022-08-01
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-05-rubicon-findings/issues/17
- Library page: https://bugbountylibrary.com/r/c4%3A2022-05-rubicon%3AH-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** RubiconRouter / RubiconMarket smart contracts
**Root cause:** offerWithETH calls RubiconMarket.offer with the router as owner instead of msg.sender, and cancelForETH lacks an ownership check tying the caller to the original depositor.
**Steps:**
1. User calls `RubiconRouter.offerWithETH(...)` sending ETH; router calls `RubiconMarket.offer` with `owner = address(this)` (router).
2. Attacker observes the offer id and calls `RubiconRouter.cancelForETH(offer_id)`.
3. cancelForETH cancels the offer and returns the escrowed ETH to the attacker.
**How found:** Code review of offerWithETH and cancelForETH: noticed the router is set as offer.owner and that cancelForETH has no check binding caller to the depositor.
**Exploitation:** Attacker monitors offers created via offerWithETH, calls cancelForETH on the offer id, and receives the ETH that the victim deposited.
**Insight:** When a router/proxy contract creates orders on behalf of users, verify who is recorded as owner and whether cancel/withdraw paths authenticate the original depositor rather than just the order id.
