# Migration total supply reduction can be used to remove minority shareholders

Migration lets proposer set arbitrary new total supply; a large reduction truncates minority contributors' shares to zero, wiping their contribution when buyout commits.

- Payout: Contest reward
- Severity: medium
- Program: Fractional
- Credited: hyh
- Disclosed: 2022-09-27
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-07-fractional-findings/issues/612
- Library page: https://bugbountylibrary.com/r/c4%3A2022-07-fractional%3AM-10
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:precision-loss

**Target:** Migration.sol vault migration contract
**Root cause:** migrateFractions() computes shareAmount = (balanceContributedInEth * newTotalSupply) / totalInEth; newTotalSupply is arbitrary and unconstrained, so a small new supply truncates small contributors' shares to zero.
**Steps:**
1. Proposer calls propose() with _newFractionSupply far below current supply (e.g. 100 vs 1e9).
2. Minority user contributes ETH via contribute(); shareAmount computed as (contribution * newTotalSupply) / totalInEth truncates to 0.
3. Proposer calls commit(), starting buyout; state leaves INACTIVE so leave()/withdrawContribution() revert.
4. On successful buyout, migrateFractions() transfers zero new shares to the minority contributor, losing their contribution.
**How found:** Code reading of migrateFractions() share math and noticing newTotalSupply is user-supplied and unconstrained, then tracing that commit() locks state preventing withdrawal.
**Exploitation:** Proposer sets a tiny new total supply, collects contributions, commits to buyout; minority contributors whose computed share truncates to zero receive nothing while their ETH is absorbed into the migration.
**Insight:** When a migration/redemption formula multiplies by a user-controlled total supply, check truncation: small denominators zero out small holders. Also check whether state transitions (commit) block the escape hatch (leave/withdraw) before shares are finalized.
