I have read the EIP-2891, but I don't know what is the correct way to approach the payment when the transaction occurs.

Initially I thought of doing something like this:


    // Transfer royalties fee
    (bool success1, ) = royaltiesRecipient.call{value: royaltiesAmount}("");
    require(success1, "Royalties fee transfer failure."); // <=== this can be a problem

    // Transfer sale value to seller
    (bool success2, ) = seller.call{value: saleValue}("");
    require(success2, "Seller transfer failure.");

    // Transfer NFT buyer
    IERC721(nftContractAddress).transferFrom(address(this), buyer, tokenId);

However, having read about the withdrawal pattern, there is a risk that the recipient of the royalties is a contract that makes the transaction fail, so that item will not be salable in the marketplace.

I don't think that the withdrawal pattern is a good option here, as the royalties recipient would need to be constantly tracking when and where the NFT has been sold. A better approach could be try to do the transaction, and only if it fails, apply the withdrawal pattern, but still not ideal.

Another approach could be just remove the require statement, but if the transaction fails for any other reason, it would be unfair for the royalties recipient.

How would you approach it?

2 Answers 2


Check out a ReentrancyGuard contract on OpenZeppelin. Using the modifier nonReentrant() will ensure that if the receiver is a contract, it will not be able to call the same function again until after it is finished. You will not need to apply the withdrawal pattern here (though it is never bad to be too cautious)

  • In this case, the problem is not reentrancy, but the receiver contract making the transaction fail.
    – Cloud
    Jan 16, 2022 at 7:52

Ok, so what i was planning on doing was to use Open Zeppelin Payment Splitter to be the receiver of the Royalties when sold through a Market Place.

Are you saying this will not work since the receiver would be a contract?

  • No, in this case it will work, as you control that contract, and as I have read in the documentation, PaymentSplitter follows the withdrawal pattern. The drawback here is that the royalties receivers have to be aware some way that they have funds available for withdrawal in that contact.
    – Cloud
    Jan 20, 2022 at 9:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.