# InitialETHCrowdfund + ReraiseETHCrowdfund: batchContributeFor function may not refund ETH which leads to loss of funds

batchContributeFor deducts each contribution's ETH before the call and never restores it on failure, so failed contributions are silently kept instead of refunded.

- Payout: Contest reward
- Severity: high
- Program: PartyDAO
- Credited: HollaDieWaldfee
- Disclosed: 2023-06-23
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-04-party-findings/issues/7
- Library page: https://bugbountylibrary.com/r/c4%3A2023-04-party%3AH-07
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** InitialETHCrowdfund / ReraiseETHCrowdfund Solidity contracts
**Root cause:** ethAvailable is decremented before each contributeFor subcall, but on failure with revertOnFailure=false the branch neither reverts nor re-adds the value, so the failed contribution's ETH stays in the contract and is never refunded.
**Steps:**
1. Deploy InitialETHCrowdfund with minContributions=1 ether, maxTotalContributions=5 ether.
2. Call `batchContributeFor{value: 2.5 ether}` with values `[1 ether, 1 ether, 0.5 ether]` and `revertOnFailure: false`.
3. Third subcall reverts (below minContribution); loop continues without restoring ethAvailable.
4. Final refund is 0; sender loses the 0.5 ether.
**How found:** Code reading of the batchContributeFor loop: noticed ethAvailable -= args.values[i] happens unconditionally before the call, while the failure branch only conditionally reverts, leaving the accounting inconsistent.
**Exploitation:** Any user calling batchContributeFor with revertOnFailure=false and a failing entry (e.g. below minContribution, gate failure, max cap) permanently forfeits that entry's ETH to the contract; no attacker needed, loss is direct to the caller.
**Insight:** In batch wrappers that pre-deduct msg.value per iteration, check that the deduction is rolled back on the non-reverting failure path; the same pattern existed in the out-of-scope Crowdfund.batchContributeFor.
