# FeeWrapper fails to handle ETH payment refunds

FeeWrapper lacks receive/fallback, so wrapped calls to targets that refund unspent ETH (e.g. RubiconRouter.buyAllAmountWithETH) revert, blocking legitimate ETH-wrapped calls.

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

**Target:** FeeWrapper utility contract wrapping payable calls
**Root cause:** FeeWrapper forwards ETH to the target but implements no receive/fallback, so any ETH refunded by the target to FeeWrapper reverts the low-level call.
**Steps:**
1. Deploy target whose function refunds part of msg.value to msg.sender (e.g. RubiconRouter.buyAllAmountWithETH refunds unspent WETH as ETH).
2. Call `feeWrapper.rubicall{value: amount+fee}(callParams)` with feeToken=address(0), totalAmount, feeAmount, target set.
3. FeeWrapper._rubicallPayable forwards value to target; target calls `msg.sender.call{value: delta}` back to FeeWrapper.
4. FeeWrapper has no receive/fallback, refund fails, target reverts, `require(_OK)` reverts with 'low-level call to the router failed'.
**How found:** Code review of _rubicallPayable noticed ETH is forwarded to target but no receive/fallback exists; cross-referenced RubiconRouter.buyAllAmountWithETH which refunds unspent ETH to msg.sender, confirming the refund path would hit FeeWrapper.
**Insight:** When auditing wrapper/proxy contracts that forward native value, check whether the downstream target can send ETH back (refunds, change, excess payment) — a missing receive/fallback turns normal target behavior into a hard revert.
