# GroupBuys that are completely filled still don't raise stated target amount

GroupBuy pool's minBidPrice computed via floor division lets a fully-filled pool collect less than the NFT's target price, causing purchase() to revert.

- Payout: Contest reward
- Severity: medium
- Program: Tessera
- Credited: Trust
- Disclosed: 2023-04-18
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-12-tessera-findings/issues/49
- Library page: https://bugbountylibrary.com/r/c4%3A2022-12-tessera%3AM-09
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:precision-loss

**Target:** GroupBuy.sol contribution pool contract
**Root cause:** minBidPrices = _initialPrice / _totalSupply rounds down, so minBidPrice * totalSupply < _initialPrice; purchase() then reverts because _price exceeds minReservePrices * filledQuantities.
**Steps:**
1. Call `createPool()` with `_initialPrice=100`, `_totalSupply=8`; minBidPrices becomes `100/8=12`.
2. Contributors fill all 8 Raes at minBidPrice 12, collecting 96 ETH.
3. Call `purchase()` with `_price=100`; check `100 > minReservePrices*8 = 96` is true, reverting `InvalidPurchase()`.
4. Pool is fully filled but cannot fund the NFT purchase.
**How found:** Code-reading of createPool's minBidPrice calculation and noticing integer division truncation breaks the invariant minBidPrice*totalSupply==initialPrice.
**Insight:** When a contract derives a per-unit price from a total via integer division, check whether totalSupply*unitPrice can fall short of the target; floor division on share/price math silently underfunds fully-subscribed pools.
