erc20

How can you give a smart contract approval to use your ERC20 token? Is there any way to transfer a token through a smart contract other than approve?


I am trying to use OpenZeppelin's approve and transferfrom functions to let me use a smart contract to transfer my ERC20 tokens.

I have found people saying you just need to use token.approve(address(this), amount) but what I have found is that it is just allowing your smart contract to spend it's nonexistent tokens.

Is there a way to specify who the owner of the tokens are instead of the owner being the smart contract?

Here is my code:

// contracts/AccruedInterest.sol
// paste me into REMIX when done
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

//import do not work on VSCode; wait until put into REMIX
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract AccruedInterest {

    //address of token contract
    ERC20 token;
    constructor () {
        token = ERC20(0x...);
    //area of problem vvv
        token.approve(address(this), 10000);
    }

    function distribute() public {

        address owneraddress = 0xOWNER;
        address placetotransfer - 0xPLACE
        token.transferFrom(owneraddress, placetotransfer, 10000);
        
    }

}


To me, this code means that the smart contract is allowed to use my tokens. However, in the terminal, it shows that the smart contract is allowing itself to use its own tokens -- Logs showing the approve event


Solution

  • constructor () {
        token = ERC20(0x...);
    //area of problem vvv
        token.approve(address(this), 10000);
    }
    

    In this case, the caller of the approve() function is the AccruedInterest contract - not the user.

    So the AccruedInterest contract approves whoever is in the first agument to spend AccruedInterest's tokens. In this case, the first argument is its own address. So in the code above, the contract only approves itself to spend its own tokens.

    If you want the user to give approval to your contract, it needs to be done through a separate transaction.

    1. User calls approve() on the token contract directly from their own address (not through another contract), and passes the AccruedInterest address as the first argument.
    2. Only then the AccruedInterest can successfully call token.transferFrom()