# Fees Are Incorrectly Charged on Unfinalized NFT Sales

Accepting an offer on an unfinalized auction NFT marks first sale complete, so the creator's primary fee is skipped and only secondary fees apply.

- Payout: Audit contest
- Severity: medium
- Program: Foundation
- Found by: leastwood
- Disclosed: 2022-05-19
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-02-foundation-findings/issues/73
- Library page: https://bugbountylibrary.com/r/c4%3A2022-02-foundation%3AM-18
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:fee-bypass

**Target:** NFTMarketOffer/NFTMarketReserveAuction/NFTMarketFees Solidity mixins
**Root cause:** _acceptOffer calls _distributeFunds before _transferFromEscrow finalizes the pending auction, so the offer sale sets _nftContractToTokenIdToFirstSaleCompleted=true before the original auction sale is settled.
**Steps:**
1. Alice creates auction for NFT; Bob is highest bidder; auction ends but Alice does not finalize.
2. Carol makes an offer; Bob (auction.bidder) accepts via `_acceptOffer()`.
3. `_distributeFunds()` runs for Bob-Carol sale first, setting `_nftContractToTokenIdToFirstSaleCompleted` to true.
4. Original Alice-Bob auction sale later settles as secondary, charging only secondary foundation fee.
**How found:** Code reading of the ordering between `_distributeFunds` and `_transferFromEscrow` in `_acceptOffer`, noticing first-sale flag set by the wrong trade.
**Exploitation:** Auction winner resells via offer acceptance before finalization, causing the creator's primary fee to be bypassed and only secondary fee charged on the original sale.
**Insight:** When a protocol tracks 'first sale' state, check whether settlement ordering across pending/queued trades can set that flag from a later trade before the earlier one settles.
