erc-20 – How to Resolve ERC20: Insufficient Allowance Error

allowanceerc-20

i intend to use my erc20 token for doing some payment for minting nft.
but when i call testPay function always got ERC20: insufficient allowance error.

already looking for answer but can't find one.

can someone tellme what i do wrong here?

msg.sender already have some erc20 token.
address(this) don't have token.
this contract is not my real nft minting contract, i just want to test the payment function.

contract GameItem is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    ERC20 public GXGToken;

    constructor(address mytoken) ERC721("GameItem", "ITM") {
        GXGToken = ERC20(mytoken);
    }

    function awardItem(address player, string memory tokenURI)
        public
        returns (uint256)
    {
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(player, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;
    }

    function approval(uint amount) public{
        GXGToken.approve(msg.sender,amount);
    }

    function myallowance() view public returns (uint){
        return GXGToken.allowance(msg.sender,address(this));
    }

    function testpay(uint _amount) public{
        GXGToken.approve(msg.sender,_amount);
        pay(_amount);
    }

    function pay(uint _amount) internal{
        GXGToken.transferFrom(msg.sender,address(this),_amount);
    }
}

Edited:
ok got it, thanks for all for the replies.

this is what i'm doing.

so i call approve function on erc20 first, approving erc721 address, and amount, then call the transferFrom on erc721 contract, param1 is sender and param2 is erc721 address.

and it's working.

Best Answer

msg.sender will have to approve GameItem smart contract address before transferFrom can be initialized to work, you were trying to transfer from the sender and the sender is yet to approve the contract address it won't work, the declaration that you here

GXGToken.approve(msg.sender,_amount);

GXGToken token has an approve function, the user must interact with GXGToken token contract address direct and use it approval function to approve GameItem smart contract address before the user (address) before the user(address) will call the function.

approve(GameItem smart contract address, _amount);

your intention was that it would automatically set the msg.sender to approve the GameItem smart contract address, it doesn't work that way.

the solution here can explain the use case of Approval and transferFrom excplicitly: What is the use case of transferFrom function in ERC20 token contract?

Related Topic