Dear Ethereum/Solidity developers,

I have a small solidity contract which should allow the contract to spend the owner's ERC20 tokens. I currently have the following interface defined

interface IERC20 {
    function totalSupply() external view returns (uint);
    function balanceOf(address account) external view returns (uint);
    function transfer(address recipient, uint amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint);
    function approve(address spender, uint amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    event Transfer(address indexed from, address indexed to, uint value);
    event Approval(address indexed owner, address indexed spender, uint value);

In the contract I use the IERC20 interface as follows:

contract MyContract {
    function myFunction(address _tokenIn, uint256 _amountIn) external {
        IERC20(_tokenIn).approve(msg.sender, _amountIn);
        IERC20(_tokenIn).transferFrom(msg.sender, address(this), _amountIn);

When I deploy this contract to the JVM or Injected Web3 provider using the remix compiler the contract throws exceptions on the first call IERC20(_tokenIn).approve(msg.sender, _amountIn);

I tried omitting the .approve() call but according to the documentation I've read the approve is required.

My experience with Solidity is rather limited, I'm afraid I might've wrongly understood the way to implement this. Is there something that i'm doing wrong? Why is the contract not allowed to spend ERC20 tokens from the function caller?

Remix throws a rather obscure error in the sense that the function should be payable, however, adding payable to the function signature does not help.

Maybe not entirely clear but to paraphrase, How do I allow my contract to spend the ERC20 tokens of the function caller?

If any additional information is required or my explanation was not clear enough, please let me know so I can update the original question.

  • Hi @Morten. Thanks for the link, will check!
    – ndury
    Commented May 27, 2021 at 18:18

1 Answer 1


I had some experiences with the function you are using, and as far as I gather. It is impossible to allow others (other addresses) to spend your/user tokens.

The approve() function here, is instead used to verify the amount of tokens you wish to transfer by using transferFrom()


You have 1000Tokens on address1 and wish to transfer 100 to address2

First, you will have to approve that amount.

approve(address1, 100)

And then transfer it by yourself.

transferFrom(address1, address2)

No other address/contract can do that call for you.

  • Hello @Sky. Thanks for taking the time to reply, perhaps i've misphrased, The only user the contract will be spending tokens of is the contract owner, no one else will be able to call the functions as they will be protected by AdminOnly permission functionality.
    – ndury
    Commented May 27, 2021 at 18:20
  • No one can spend tokens from the other address, for the contract to be able to do it, it would need to have another wallet's private key(big security no-no), or pre-signed transaction that would have to be sent by the wallet's owner every time contracts wants to spend funds.
    – Sky
    Commented May 29, 2021 at 22:31

Not the answer you're looking for? Browse other questions tagged or ask your own question.