Skip to main content
Sigvex

Royalty Bypass

Detects NFT marketplace and token contracts where ERC-2981 royalty payments can be circumvented through wrapper contracts or direct transfers.

Royalty Bypass

Overview

Remediation Guide: How to Fix Royalty Bypass

The royalty bypass detector identifies contracts where ERC-2981 royalty payments can be circumvented. This includes marketplace contracts that do not enforce royalty queries, wrapper contracts that hide the original NFT during transfer, and direct ERC-721/1155 transfers that bypass the marketplace entirely.

Why This Is an Issue

ERC-2981 royalties are advisory – the standard provides a royaltyInfo function but does not enforce payment. Marketplaces must query and enforce royalties voluntarily. Bypasses include:

  • Direct transferFrom outside the marketplace
  • Wrapper contracts that hold the NFT and transfer the wrapper token
  • Marketplace contracts that query royaltyInfo but do not send the payment

Creator revenue depends on royalty enforcement. Bypass-friendly marketplaces have caused significant revenue loss for NFT creators.

How to Resolve

// Before: Marketplace ignores royalties
function executeSale(uint256 tokenId, uint256 price) external payable {
    require(msg.value >= price);
    nft.transferFrom(seller, msg.sender, tokenId);
    payable(seller).transfer(price); // No royalty paid
}

// After: Query and enforce ERC-2981 royalties
function executeSale(uint256 tokenId, uint256 price) external payable {
    require(msg.value >= price);
    (address receiver, uint256 royalty) = IERC2981(address(nft)).royaltyInfo(tokenId, price);
    require(royalty <= price, "Royalty exceeds price");
    nft.transferFrom(seller, msg.sender, tokenId);
    if (royalty > 0 && receiver != address(0)) {
        payable(receiver).transfer(royalty);
    }
    payable(seller).transfer(price - royalty);
}

Examples

Sample Sigvex Output

{
  "detector_id": "royalty-bypass",
  "severity": "medium",
  "confidence": 0.68,
  "description": "NFT sale function at offset 0x5c transfers ERC-721 token and sends full payment to seller without querying ERC-2981 royaltyInfo(). Creator royalties are not enforced.",
  "location": { "function": "executeSale(uint256,uint256)", "offset": 92 }
}

Detection Methodology

  1. Sale pattern detection: Identifies functions that transfer ERC-721/1155 tokens in exchange for ETH or ERC-20 payment.
  2. Royalty query check: Verifies whether royaltyInfo is called before or after the transfer.
  3. Payment verification: Checks whether the royalty amount is actually sent to the royalty receiver.
  4. Wrapper detection: Identifies contracts that wrap NFTs to circumvent transfer restrictions.

Limitations

  • Cannot enforce royalties for direct peer-to-peer transfers outside marketplace contracts.
  • ERC-2981 support detection relies on selector matching; non-standard royalty interfaces may not be recognized.

References