Despite using the receive() function, my contract is not receiving payment in Remix

Viewed 109

I am writing a smart contract in Remix with Solidity. The purpose of the contract is to allow a user to mint an NFT for 1 ETH. At present, the user is able to mint and the contract accepts the payment (ie. the user's balance is properly subtracted). But when I check the address(this).balance of the contract with my accountBalance() function, the function returns 0. I have included the receive() function as per the Solidity docs:

event Received(address, uint);
    receive() external payable {
        emit Received(msg.sender, msg.value);
    }

Can someone explain why this is happening and what I need to change about my contract? Here is my contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

// imports
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/security/PullPayment.sol';

// contract
contract RobocopPoster is ERC721, Ownable, PullPayment {

    // constants
    uint256 public mintPrice;
    uint256 public totalSupply;
    uint256 public maxSupply;
    uint256 public maxPerWallet;
    bool public mintEnabled;
    mapping (address => uint256) public walletMints;

    // constructor
        // initialize variables
    constructor() payable ERC721('RobocopPoster', 'SFFPC') {
        mintPrice = 1 ether;
        totalSupply = 0;
        maxSupply = 1000;
        maxPerWallet = 3;
    }

    event Received(address, uint);
    receive() external payable {
        emit Received(msg.sender, msg.value);
    }

    // functions
    function setMintEnabled(bool mintEnabled_) external onlyOwner {
        mintEnabled = mintEnabled_;
    }

    function withdrawPayments(address payable payee) public override onlyOwner virtual {
        super.withdrawPayments(payee);
    }

    function accountBalance() public view returns (uint256) {
        return (address(this).balance);
    }

    function mint(uint256 quantity_) public payable {
        require(mintEnabled, 'Minting not enabled.');
        require(msg.value == quantity_ * mintPrice, 'wrong mint value');
        require(totalSupply + quantity_ <= maxSupply, 'sold out');
        require(walletMints[msg.sender] + quantity_ <= maxPerWallet, 'exceed max wallet');
        walletMints[msg.sender] += quantity_;
        _asyncTransfer(address(this), msg.value);

        for (uint i = 0; i < quantity_; i++) {
            uint256 newTokenId = totalSupply + 1;
            totalSupply++;
            _safeMint(msg.sender, newTokenId);
        }
    }
}
1 Answers

You need to call withdrawPayments to receive the fund, because _asyncTransfer from PullPayment in your contract minting sent the fund to the escrow contract. That's why you saw zero balance in ERC721 contract.

Related