# Residual ETH not sent back when `batchBalanceAndTradeAction` executed

Residual native ETH refunded by Notional V3 during batchBalanceAndTradeAction was never wrapped to WETH, so excess ETH stayed stuck in the wfCash wrapper instead of reaching users.

- Payout: Contest reward
- Severity: high
- Program: Notional Update 5
- Credited: bin2chen
- Disclosed: 2023-12-20
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-12-notional-update-5-judging/issues/30
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-12-notional-update-5%3AH-3
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:business-logic

**Target:** wrapped-fcash wfCashLogic _lendLegacy / _sendTokensToReceiver
**Root cause:** Notional V3's depositUnderlyingExternal returns excess msg.value as native ETH to the wrapper, but _sendTokensToReceiver only measures WETH.balanceOf and never wraps the received native ETH, so the refund is stranded.
**Steps:**
1. Call wfCash _lendLegacy with msg.value exceeding the cost to purchase fCashAmount.
2. NotionalV2.batchBalanceAndTradeAction{value: msgValue} triggers depositUnderlyingExternal, which sends msg.value - underlyingExternalDeposit native ETH back to the wrapper.
3. _sendTokensToReceiver computes tokensTransferred from WETH.balanceOf only; native ETH is not wrapped, so residual stays in contract.
4. User receives less than deposited; excess ETH locked in wrapper.
**How found:** Code-reading of the comment claiming residual ETH is wrapped by _sendTokensToReceiver, then verifying the implementation only reads WETH balance and never calls WETH.deposit on received native ETH.
**Exploitation:** Any user lending via the ETH path with an overpayment loses the residual; no attacker action needed beyond normal use, funds accumulate in the wrapper.
**Insight:** When a comment asserts a token conversion happens downstream, verify the actual balance source in the receiving function: measuring WETH.balanceOf ignores native ETH delivered by the callee, so refunds silently strand.
