# Users wouldn't refund from the lost ETH crowdfunds due to the lack of ETH

Rounding in ETHCrowdfundBase fee subtraction makes _calculateRefundAmount return more than contributed, so refund() reverts and users cannot reclaim lost-crowdfund ETH.

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

**Target:** ETHCrowdfundBase refund calculation
**Root cause:** Contribution fee is computed as floor(amount*bps/1e4) and subtracted, rounding the post-fee amount up; refund recomputes original via division by (1e4-bps), which can exceed the actual contributed amount.
**Steps:**
1. Set fundingSplitBps=1000 (10%), exchangeRateBps=1e4.
2. Contribute `1 ether - 1` wei; stored voting power = `9e17` after fee.
3. Skip duration so lifecycle is Lost.
4. Call `refund(tokenId)`; `_calculateRefundAmount` returns `9e17*1e4/9000 = 1e18`, exceeding contract balance `1e18-1`.
5. Transfer reverts; refund blocked.
**How found:** Code review of fee subtraction in _processContribution versus inverse computation in _calculateRefundAmount; noticed floor rounding asymmetry produces a refund larger than contribution, confirmed with Foundry PoC.
**Exploitation:** Any contributor to a lost ETH crowdfund with a funding split recipient can be permanently unable to refund because the computed refund exceeds the contract's ETH balance, reverting the transfer.
**Insight:** When a fee is subtracted with floor division and later inverted by dividing by (1e4-bps), rounding asymmetry can inflate the reconstructed amount; check inverse functions for round-trip consistency and test with amounts like `X-1` wei.
