Implementing a 2.5% commission on NFT sales in a marketplace contract

I’m working on an NFT marketplace and I’ve hit a snag. Everything else works fine, but I’m struggling to add a 2.5% fee on each sale. I originally had a fixed fee of 0.1 ETH, but now I want to change that.

Here’s a simplified version of my contract function:

function sellNFT(uint256 itemId) public payable {
    uint256 price = items[itemId].price;
    require(msg.value == price, "Wrong price");
    
    // Transfer NFT and payment
    items[itemId].seller.transfer(msg.value);
    nftContract.transferFrom(address(this), msg.sender, items[itemId].tokenId);
    
    // Try to transfer commission
    uint256 commission = (price * 25) / 1000; // 2.5%
    payable(owner).transfer(commission);
}

And here’s how I’m calling it from my frontend:

async function buyItem(itemId, price) {
    const contract = new ethers.Contract(marketAddress, ABI, signer);
    const ethPrice = ethers.utils.parseEther(price);
    
    await contract.sellNFT(itemId, { value: ethPrice });
}

The problem is, I keep getting an error stating that the transaction was reverted when it tries to transfer the commission. What am I doing wrong here? Any ideas on how to fix this?

I’ve encountered a similar issue in my NFT marketplace project. The problem lies in attempting to transfer more ETH than the contract holds. To resolve this, you need to adjust the payment distribution.

Modify your sellNFT function as follows:

function sellNFT(uint256 itemId) public payable {
    uint256 price = items[itemId].price;
    require(msg.value == price, "Incorrect price");
    
    uint256 commission = (price * 25) / 1000;
    uint256 sellerAmount = price - commission;
    
    items[itemId].seller.transfer(sellerAmount);
    payable(owner).transfer(commission);
    nftContract.transferFrom(address(this), msg.sender, items[itemId].tokenId);
}

This ensures the seller receives the price minus the commission, while the owner gets the commission. No changes are needed in your frontend code. Remember to thoroughly test the updated function to confirm it works as expected.

hey there ethan! i’ve been messing around with nft marketplace contracts too and i think i see what’s going on with your code. :thinking:

The issue is probably that you’re trying to transfer the full price to the seller and then also transfer a commission, but there’s not enough eth left in the contract to do both.

Here’s a quick fix you could try:

function sellNFT(uint256 itemId) public payable {
    uint256 price = items[itemId].price;
    require(msg.value == price, "Wrong price");
    
    uint256 commission = (price * 25) / 1000; // 2.5%
    uint256 sellerPayment = price - commission;
    
    // Transfer NFT and payments
    items[itemId].seller.transfer(sellerPayment);
    payable(owner).transfer(commission);
    nftContract.transferFrom(address(this), msg.sender, items[itemId].tokenId);
}

This way, you’re splitting the payment before sending it out. The seller gets the price minus the commission, and the owner gets the commission.

Have you considered using the transfer() function instead of call() for extra safety? Might be worth looking into!

Let me know if this helps or if you need any more info. Good luck with your marketplace!