# migrateFractions may be called more than once by the same user which may lead to loss of tokens for other users

Migration.migrateFractions lacked a per-user claimed check, letting a user call it repeatedly to drain new vault tokens owed to other migrators.

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

**Target:** Migration.sol migrateFractions function (Solidity vault migration contract)
**Root cause:** migrateFractions computes and transfers new vault tokens from stored userProposalEth/userProposalFractions but never zeroes or marks them claimed, so the same contribution can be redeemed repeatedly.
**Steps:**
1. Deploy/settle migration via testSettle() so Migration holds TOTAL_SUPPLY*2 new tokens.
2. Alice (4000 fractions) calls `migrationModule.migrateFractions(vault, 1)` -> receives 6000 new tokens.
3. Alice calls `migrateFractions(vault, 1)` again -> receives another 6000 new tokens (balance 12000).
4. Bob calls `migrateFractions(vault, 1)` -> reverts with arithmeticError because Migration no longer holds enough tokens.
**How found:** Code review of the migration claim logic: noticed no guard/state reset preventing repeat calls for the same user, then wrote a Foundry test calling migrateFractions twice for one user and once for another to demonstrate the drain and revert.
**Exploitation:** A single migrating user repeatedly invokes migrateFractions to withdraw more new-vault tokens than their contribution entitles them to, depleting the Migration contract's token balance so later legitimate migrators cannot claim and lose their owed tokens.
**Insight:** For any claim/migration function that pays out based on stored per-user contribution amounts, check whether the contribution state is zeroed or a claimed flag set after payout; test calling the claim twice from the same account before others claim.
