I’m struggling to understand how to correctly implement royalty payments using the ERC2981 standard in my NFT marketplace contract. I’ve looked through documentation but I’m still confused about several key concepts.
Specifically, I need help understanding what the feeNumerator parameter represents in the _setDefaultRoyalty(address recipient, uint96 feeNumerator) function. Does this value represent the actual NFT price or is it the royalty percentage?
Here’s my current smart contract implementation. Can someone review it and tell me if I’m handling the royalty setup correctly?
// SPDX-License-Identifier: MIT
pragma solidity 0.8.8;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/token/common/ERC2981.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
contract AudioWave is ERC721URIStorage, ERC2981, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenCounter;
Counters.Counter private _itemCounter;
struct AudioNFT {
address creator;
address currentOwner;
string tokenName;
string tokenDesc;
uint256 tokenValue;
uint256 royaltyRate;
uint256 tokenId;
bool isListed;
}
mapping(uint256 => AudioNFT) public audioItems;
constructor() ERC721("AudioWave Tokens", "AUDIO") {}
function createToken(
string memory metadataURI,
string memory _tokenName,
string memory _tokenDesc,
uint256 _tokenValue,
uint256 _royaltyRate) public returns(uint256) {
require(_tokenValue > 0, "Token value must be greater than zero");
require(_royaltyRate > 0 && _royaltyRate <= 25, "Royalty rate must be between 1-25 percent");
_itemCounter.increment();
_tokenCounter.increment();
uint256 newTokenId = _tokenCounter.current();
_safeMint(msg.sender, newTokenId);
_setTokenURI(newTokenId, metadataURI);
audioItems[_itemCounter.current()] = AudioNFT(
payable(msg.sender),
payable(msg.sender),
_tokenName,
_tokenDesc,
_tokenValue,
_royaltyRate,
newTokenId,
false
);
return newTokenId;
}
function makeAvailable(uint256 _itemId) public {
require(msg.sender == audioItems[_itemId].currentOwner && msg.sender == audioItems[_itemId].creator, "Only token owner can list for sale");
audioItems[_itemId].isListed = true;
approve(address(this), audioItems[_itemId].tokenId);
setApprovalForAll(address(this), true);
_setDefaultRoyalty(audioItems[_itemId].creator, uint96(audioItems[_itemId].royaltyRate));
}
}
Any guidance on whether this implementation is correct would be really helpful. Thanks for your time!