# Creators can steal sale revenue from owners' sales

Creator adds seller as royalty recipient via Royalty Registry, making isCreator true so all sale revenue goes to creator, leaving owner with zero.

- Payout: Audit contest
- Severity: high
- Program: Foundation
- Found by: IllIllI
- Disclosed: 2022-05-19
- Write-up quality: 8/10
- Original: https://github.com/code-423n4/2022-02-foundation-findings/issues/30
- Library page: https://bugbountylibrary.com/r/c4%3A2022-02-foundation%3AH-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:accounting-error vuln:business-logic

**Target:** NFTMarketCreators/NFTMarketFees royalty resolution in NFT marketplace contract
**Root cause:** _getCreatorPaymentInfo returns isCreator=true whenever any royalty recipient equals the seller, and _getFees then routes the entire price minus fee to creatorRev, zeroing ownerRev. Royalty Registry lets creator set recipients arbitrarily right before sale.
**Steps:**
1. Creator registers a royalty override via Royalty Registry returning recipients including the current seller address.
2. Owner lists NFT and a buyer completes the sale.
3. _getCreatorPaymentInfo hits the IGetRoyalties branch, sees _recipients[i] == seller, returns isCreator=true.
4. _getFees sets creatorRev = price - foundationFee and leaves ownerRev = 0.
5. Seller receives nothing; creator collects full sale proceeds minus fee.
**How found:** Read README claim that Royalty Registry is respected, then traced _getCreatorPaymentInfo's isCreator flag into _getFees and noticed isCreator conflates 'seller is a royalty recipient' with 'seller is the creator', letting registry override flip revenue routing.
**Exploitation:** Creator waits for a secondary sale, updates Royalty Registry so the seller address appears among recipients, then the sale pays creatorRev=price-fee to creator and zero to owner. Can be applied selectively per sale; creator may bribe/kickback to collude.
**Escalation:** Also if seller index exceeds MAX_ROYALTY_RECIPIENTS_INDEX, seller is omitted and gets zero via _sendValueWithFallbackWithdraw.
**Insight:** When a contract derives a privileged boolean (isCreator) from an attacker-controllable registry lookup, check whether any recipient matching the seller address flips revenue routing; royalty/override registries are a lever to weaponize per-sale.
