Issue with Token Payment for NFT Minting
I’m working with two contracts - an ERC1155 NFT contract and an ERC20 token contract. Users should be able to buy NFTs using my custom ERC20 tokens, but I keep getting this error: ERC20: transfer amount exceeds allowance
when calling transferFrom()
.
My NFT Contract (ERC1155):
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract GameItemNFT is ERC1155, Ownable {
IERC20 private _paymentToken;
constructor(IERC20 paymentToken)
ERC1155(
"ipfs://QmSampleHash123/metadata/{id}.json"
)
{
_paymentToken = paymentToken;
}
function purchaseItem(
address buyer,
uint256 tokenId,
uint256 quantity
) public {
require(_paymentToken.transferFrom(msg.sender, address(this), 1));
_mint(buyer, tokenId, quantity, "");
}
}
My ERC20 Token Contract:
// SPDX-License-Identifier: MIT
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
pragma solidity ^0.8.0;
contract GameToken is ERC20, Ownable {
uint256 public totalMaxSupply = 50000 * 10**18;
constructor() ERC20("Game Coin", "GAME") {
_mint(msg.sender, totalMaxSupply);
}
function rewardPlayer(
address player,
uint256 tokens,
bool taskCompleted
) public onlyOwner {
require(taskCompleted == true);
_mint(player, tokens);
}
function setNFTApproval(address _nftContract) public onlyOwner {
approve(_nftContract, totalMaxSupply);
}
}
Test Code:
def test_nft_purchase_with_tokens():
# Setup
owner = get_account()
buyer = get_account(1)
game_token = deploy_token_contract()
nft_contract = GameItemNFT.deploy(game_token, {"from": owner})
# Give tokens to buyer
reward_tx = game_token.rewardPlayer(buyer, 20, True)
reward_tx.wait(1)
print(f"Buyer balance: {game_token.balanceOf(buyer.address)}")
# Approve spending
approve_tx = game_token.approve(buyer.address, game_token.balanceOf(buyer.address))
approve_tx.wait(1)
# Try to mint NFT
assert nft_contract.purchaseItem(buyer.address, 15, 1, {"from": buyer})
print(f"NFT minted successfully")
What am I doing wrong here? Should the minting function be marked as payable?