# ReraiseETHCrowdfund.sol: party card transfer can be front-run by claiming pending voting power which results in a loss of the voting power

Anyone can call ReraiseETHCrowdfund.claim for another contributor, so an attacker front-runs a party card transfer by claiming the victim's pending voting power onto the card being transferred.

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

**Target:** ReraiseETHCrowdfund.claim / party card transfer
**Root cause:** claim(tokenId, contributor) is permissionless and, when disableContributingForExistingCard is false, adds pendingVotingPower[contributor] to any tokenId owned by contributor, so a third party can attach pending votes to a card mid-transfer.
**Steps:**
1. Victim owns party card tokenId and has pendingVotingPower in ReraiseETHCrowdfund.
2. Victim submits party.transferFrom(victim, recipient, tokenId).
3. Attacker front-runs: crowdfund.contribute{value: X} to finalize the crowdfund if needed, then crowdfund.claim(victimTokenId, victim).
4. claim burns victim's crowdfund NFT, deletes pendingVotingPower, and calls party.addVotingPower(victimTokenId, votingPower) since party.ownerOf(tokenId)==victim.
5. Victim's transfer then executes, moving the card with the newly added voting power to the recipient, losing that voting power.
**How found:** Code reading of claim: noticed it is callable for any contributor and can target an existing card owned by that contributor, then reasoned that a pending transfer creates a window where the card's owner still matches the contributor, enabling front-running.
**Exploitation:** Attacker observes the victim's pending transfer in the mempool, contributes enough to finalize the crowdfund, and calls claim(victimTokenId, victim) to bind the victim's pending voting power to the card being sold/transferred; the recipient (or attacker as buyer) gains the voting power the victim expected to keep.
**Insight:** When a permissionless function lets a third party mutate state tied to a user-chosen asset (here adding voting power to a specific tokenId), check whether an in-flight ownership-changing transaction (transfer/sale) creates a window where the pre-transfer owner check still passes, enabling front-run value capture.
