# A user might lose ETH when sending a deposit in a multicall that includes a depositOnBehalfcall

In a Size multicall, depositOnBehalfOf consumes the operator's msg.value ETH as the member's collateral, so the operator's own deposit gets nothing.

- Payout: Contest reward
- Severity: medium
- Program: Size
- Credited: mt030d
- Disclosed: 2025-04-03
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_size_february2025.pdf#3.1.3
- Library page: https://bugbountylibrary.com/r/cantina%3Asize_february2025%3A3.1.3
- Tags: domain:web3 impact:funds-loss kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Size market Deposit library / multicall deposit flow
**Root cause:** executeDeposit branches on msg.value>0 and wraps the caller's ETH as the deposit source even in depositOnBehalfOf, where the authorizer's WETH should be used; multicall forwards the whole msg.value to the first call.
**Steps:**
1. Alice authorizes Bob as operator for Action.DEPOSIT and holds 100 WETH.
2. Bob calls `size.multicall{value:100e18}([depositOnBehalfOf(weth,100e18,alice), deposit(weth,100e18,bob)])`.
3. First call sees msg.value>0, wraps Bob's 100 ETH and deposits it as Alice's collateral.
4. Second deposit call has no msg.value left, deposits zero for Bob.
**How found:** Code reading of executeDeposit's `if (msg.value > 0)` branch and the Multicall msg.value handling comment, noticing the branch ignores who the deposit is for; confirmed with a Foundry PoC comparing separate txs vs multicall.
**Exploitation:** Operator bundles depositOnBehalfOf before their own deposit in one multicall with msg.value equal to params.amount; the ETH is credited to the onBehalfOf member, leaving the operator with no collateral and lost ETH.
**Insight:** When a shared internal function branches on msg.value, check every external entrypoint that reaches it via multicall: msg.value is global to the batch, so per-call intent (who pays, who receives) can be silently reassigned to whichever call runs first.
