I have a scenario where a user approves an allowance of a standard erc20 token to a contract address using the approve function as follows using the truffle console.

TOKEN.approve("contractAddress", 10000000)

It generates a tx and when I check the allowance using the allowance function, I can see the approved allowance as

TOKEN.allowance(account[0], "contractAddress") 

It gives me the correct amount and I can also see the correct tx and data in the transaction.

The issue is when I call the same allowance function from inside a contract (where the tokens were sent to), I never get the amount.

The following function in my Contract.

function checkUserAllowance() public virtual returns (bool) {
 // load contract interface
  IERC20 TOKEN = IERC20("contractAddress"); // I can verify it is the correct address
  // check the approved allowance
  uint256 allowance = TOKEN.allowance(msg.sender, address(this));
  require(allowance > 0, "No approved allowance");

  return true;


When calling checkUserAllowance I always get the "No approved allowance" message and it never goes through. I can confirm that I am sending requests from the correct user.

Any idea what am I doing wrong?


3 Answers 3


I don't know if it helps, but:

When instantiating the ERC20 I see

 IERC20 TOKEN = IERC20("contractAddress");

If you mean here by "contractAddress" the ERC20 address, then it should actually work.

The first "contractAddress" and "toAddress" are the same right?

Hope it helps!

  • Yes that is correct, both toAddress and contractAddress are the same and it is a standard erc20 contract
    – Ali
    Jan 8, 2023 at 14:52

This might help someone one day, so if you making a simple call to a function there is a chance that the function is executed before the msg.sender is filled. In that case as a workaround and if it is safe for your function to have msg.sender as an address as a parameter such as following

function checkUserAllowance(address sender) public virtual returns (bool){..}

If it is unsafe for your function to receive sender's address as a parameter (highly depends on your requirements) then you need use transaction (instead of just calling the function) which fills the msg.sender first before executing the function as transaction means you want to change the state of the blockchain.

for more : https://stackoverflow.com/questions/51847788/msg-sender-does-not-work-inside-a-view-function-why-is-there-a-workaround


Your code looks correct but i think when you calling token contract through your contract, msg.sender of this function is your contract, so this will returns you allowance which both of owner and spender are your contract address.

I hope it helps you because i'm nut sure 100% but it should be work


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.