I realized that you need to approve the amount of tokens you are gonna send to contract. for this you should first use approve function in token contract and then call the trasferfrom function in other contract (for example buy function)

But is there any way to use approve function in the same buy function? when I use approve function, I get error. I checked the value of msg.sender... it is the user who is calling the function but i still get error. i dont want to use approve function from token contract every time before i want to call buy function from Buy contract. Here is the code: (extra codes are not pasted here)

pragma solidity >=0.6.0 <0.8.0;
contract ERC20{
function approve(address spender, uint256 amount) public returns (bool) {        
    require(msg.sender != address(0), "ERC20: approve from the zero address");
    require(spender != address(0), "ERC20: approve to the zero address");
    _allowances[msg.sender][spender] = amount;
    emit Approval(msg.sender, spender, amount);
    return true;

function approveWithSender(address sender, address spender, uint256 amount) external returns (bool) {        
    require(sender != address(0), "ERC20: approve from the zero address");
    require(spender != address(0), "ERC20: approve to the zero address");
    require(sender == msg.sender,"You cannot approve other users");
    _allowances[sender][spender] = amount;
    emit Approval(sender, spender, amount);
    return true;

contract Buy{

ERC20 tokenAddress;
address contractAddress = address(this);

constructor (address _tokenAddress) public{
    tokenAddress = ERC20(_tokenAddress);

function buy(uint amount) public{
    //tokenAddress.approveWithSender(msg.sender, contractAddress, amount);
    //tokenAddress.approve(contractAddress, amount);
    require(amount > 0, "You need to sell at least some tokens");
    uint256 allowance = tokenAddress.allowance(msg.sender, address(this));
    require(allowance >= amount, "Check the token allowance");
    tokenAddress.transferFrom(msg.sender, contractAddress, amount);

in case of using approve() function I get revert error, even tho the msg.sender is the user who is calling the function?

in case of using approveWithSender() I get "You cannot approve other users" Error defiend in Token contract.

  • Comments are not for extended discussion; this conversation has been moved to chat.
    – eth
    Commented Dec 26, 2020 at 9:15

1 Answer 1


It is a shortcoming of EIP-20 compatible tokens.

Alternative options:

  • EIP-777 A token specification backward compatible EIP-20.

  • EIP 2612 A way to add permissions on top EIP-20 that allows compatible tokens single transaction transfers. DAI and UNI have an early implementation.

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