When I called fransferFrom by using erc20 interface (IERC20), an error says "gas required exceeds allowance (10000000) or always failing transaction".

I made allowance for the contract beforehand.

This is the contract that call transferFrom.

pragma solidity ^0.6.7;

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

contract TokenSale {

    address public token_address;

    constructor(address _token_address) public {
        token_address = _token_address;
    function sendEtherFromDeposit(address _token_supplyer) public returns(bool success) { 
        require(IERC20(token_address).allowance(_token_supplyer, address(this)) >= 10000, "insufficient allowance amount");
        IERC20(token_address).transferFrom(address(this), msg.sender, 1000);
        success = true;

Are there any problem of my code? Could you give me any advise, please?

  • Did you call approve beforehand? Sep 2, 2020 at 7:05
  • BTW, please fix your code. There is no such variable icb_address. Same goes for _icb_supplyer. There is also no local variable _token_address in the constructor. On top of all of that, the opening statement of your question makes no sense descriptive-wise. This question is in poor condition! Sep 2, 2020 at 7:07
  • Sorry for my poor English,, I fixed my contract.
    – gnxvw
    Sep 2, 2020 at 23:56

1 Answer 1


You're currently trying to send tokens from the contract itself, rather than from _token_supplyer (which I assume is what you intended to do). The first parameter of transferFrom specifies the address to send the tokens for, so if you set it to address(this), the token tries to send tokens from the contract, but fails because you didn't set the allowance or the contract doesn't have enough balance.

It will work if you specify _token_supplyer as first parameter instead:

IERC20(token_address).transferFrom(_token_supplyer, msg.sender, 1000);

The token contract can check if _token_supplyer has allowed the contract to spend tokens by checking msg.sender. You don't need to specify the contract address itself in transferFrom.


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.