Allowance shows value, token contract says insufficient allowance

Hi, i am working on a side game contract. This contract receives tokens from another contract, when the contracts balance has reached an minimum amount of tokens, the first caller to call the function, will burn the balance of tokens and receives 1% of the balance as reward for doing so.

In order to approve the caller to spend the contract's token balance, i used this:

  function approve() public {
    approveBurn(msg.sender);
  }

  function approveBurn(address spender) internal {
    // Add some (alot) extra allowance in case more comes in
    uint256 extraAllowance = erc20Token.balanceOf(address(this)) * 100**18;
    uint256 amount = erc20Token.balanceOf(address(this)) + extraAllowance;
    erc20Token.approve(spender, amount);
    emit Approval (address(this), spender, amount);
  }

When i go to the erc20 token contract, and check the callers allowance, it shows the correct amount (so the games balance * 100). So according to the erc20 token contract, caller have enough allowance to spend the games balance.

However, when the caller calls the function to burn the balance and receive the reward, done with this:

   IBurnableToken(erc20Token).burn(address(this), toBeBurned);
   erc20Token.transferFrom(address(this), caller, callerReward);

It reverts with "Unsufficient allowance", but when i check allowance on the token contract, the allowance for caller to spend the balance, is there, even multiplied by 100 times.

I am a bit lost here, anyone have a direction where to search?

Where exactly is that?


Also note that you don't even need an approval here to begin with, as you may as well change this:

   erc20Token.transferFrom(address(this), caller, callerReward);

To this:

   erc20Token.transfer(caller, callerReward);

Also note that this:

    uint256 extraAllowance = erc20Token.balanceOf(address(this)) * 100**18;
    uint256 amount = erc20Token.balanceOf(address(this)) + extraAllowance;

Is equivalent to this:

    uint256 amount = erc20Token.balanceOf(address(this)) * (100**18 + 1);

And hence to this:

    uint256 amount = erc20Token.balanceOf(address(this)) * (10**36 + 1);

Hi, thanks for your reply. I changed

erc20Token.transferFrom(address(this), caller, callerReward);

to

erc20Token.transfer(caller, callerReward);

and also used

  uint256 constant MAX_INT = 2**256 - 1;

as approval now.

When i delete

IBurnableToken(erc20Token).burn(address(this), toBeBurned);

then the function works but will only send 'calledReward' to caller. When i add the code above back, it throws i have insufficient allowance. What i try to do, is that by calling the function, the balance of the contract gets burned minus 1% of the total balance, which will be send to the caller.

Function that the caller can call:

  function burnThePool() public {
   // Set requirement to execute
   require (erc20Token.balanceOf(address(this)) >= minimumToBurn, "Minimum not reached yet");
   executeBurn(msg.sender);   
  }

and then the internal function:

  function executeBurn(address caller) internal {
   // Calc the reward for the caller
   uint256 callerReward = erc20Token.balanceOf(address(this)) / 100 * callerPercentage;
   // Calc the amount to be actually burned
   uint256 toBeBurned = erc20Token.balanceOf(address(this)) - callerReward;
   // Update gamedata for caller
   gameData[caller].burnedPool += 1;
   gameData[caller].totalBurned = gameData[caller].totalBurned + toBeBurned;
   gameData[caller].erc20Collected = gameData[caller].erc20Collected + callerReward;
   // Check if caller burned the most of all burns
   if (toBeBurned > biggestBurn) {
      biggestBurn = toBeBurned;
      // Set caller as new `biggestBurner`
      biggestBurner = caller;
   }
   burnedByGame = burnedByGame + toBeBurned;
   // Fire everything up
   IBurnableToken(xenToken).burn(address(this), toBeBurned);
   erc20Token.transfer(caller, callerReward);
  }

I made a public function that executes an internal function, so that msg.caller in the internal function, will be the contract its self. So im not sure why the burn part of the code, throws us unsufficient allowance, since the tokens are in the contracts balance and the contract makes the internal call.