Implementing a percentage-based commission for NFT sales

Hey guys, I’m stuck on my NFT marketplace project. I’ve got most of it working, but I’m having trouble with the commission system.

I want to add a 2.5% fee on every sale. Right now, I’m using a fixed fee of 0.1 ETH. Here’s what I’ve tried:

function sellNFT(address nftContract, uint256 itemId, uint256 fee) public payable {
    uint256 cost = listedItems[itemId].price;
    uint256 nftId = listedItems[itemId].tokenId;
    
    require(msg.value == cost, "Wrong price sent");
    
    listedItems[itemId].seller.transfer(msg.value);
    IERC721(nftContract).transferFrom(address(this), msg.sender, nftId);
    listedItems[itemId].owner = payable(msg.sender);
    listedItems[itemId].sold = true;
    soldItems.increment();
    payable(owner).transfer(fee);
}

My JS code calculates the fee like this:

const price = ethers.utils.parseUnits(nft.price.toString(), "ether");
const fee = +((2.5 / 100) * nft.price);
let commission = fee.toString();

let tx = await contract.sellNFT(nftContract, nft.itemId, commission, {
    value: price,
});

But I keep getting an error saying the transaction failed. Any ideas what I’m doing wrong? Thanks!

yo, i’ve run into this before. the issue is probably in how ur handling the commission. instead of passing it as a parameter, calculate it in the contract.

try something like this in ur contract:

function sellNFT(address nftContract, uint256 itemId) public payable {
    uint256 price = listedItems[itemId].price;
    uint256 commission = price * 25 / 1000; // 2.5% fee
    require(msg.value == price + commission, "Wrong amount sent");
    // rest of ur logic here
}

this should fix it. lmk if u need more help!

hey there ethan_witty! i’ve been tinkering with nft marketplaces too and ran into similar commission headaches. have you considered calculating the fee inside the contract instead of passing it as a parameter? that way you can make sure everything adds up correctly.

here’s a quick idea:

function sellNFT(address nftContract, uint256 itemId) public payable {
    uint256 price = listedItems[itemId].price;
    uint256 commission = (price * 25) / 1000; // 2.5% commission
    require(msg.value >= price + commission, "not enough eth sent");
    
    // transfer price to seller, commission to contract owner
    listedItems[itemId].seller.transfer(price);
    payable(owner).transfer(commission);
    
    // rest of your logic here...
}

then in your js, you’d just need to send the total amount:

const totalCost = ethers.utils.parseUnits((nft.price * 1.025).toString(), "ether");
await contract.sellNFT(nftContract, nft.itemId, { value: totalCost });

what do you think? this approach should handle the commission calculation more reliably. let me know if you try it out!

I’ve dealt with a similar issue in my NFT marketplace project. The problem is likely in how you’re handling the commission calculation and transfer. Instead of passing the fee as a parameter, calculate it within the smart contract itself. This ensures consistency and prevents potential manipulation.

Try modifying your sellNFT function like this:

function sellNFT(address nftContract, uint256 itemId) public payable {
    uint256 price = listedItems[itemId].price;
    uint256 commission = price * 25 / 1000; // 2.5% fee
    require(msg.value == price + commission, "Incorrect amount sent");

    listedItems[itemId].seller.transfer(price);
    payable(owner).transfer(commission);
    // Rest of your function logic...
}

Then in your JS, send the total amount:

const totalAmount = ethers.utils.parseUnits((nft.price * 1.025).toString(), "ether");
let tx = await contract.sellNFT(nftContract, nft.itemId, { value: totalAmount });

This approach should resolve your issue and implement the percentage-based commission correctly.