How to allow ERC20 transfer in a smartcontract with the IERC20.sol?

Viewed 13

First of all, I'm searching for how to resolve my pb for 3 days. I've read a lot of topics describing the same error, but none of them had helped me.

I ONLY need to deposit and withdraw an ERC20 token in my contract. But I have an insufficient allowance error.

execution reverted: ERC20: insufficient allowance

Here is my code :

    // SPDX-License-Identifier: Me
pragma solidity ^0.8.9;
import "hardhat/console.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract Staking {
    mapping(address => uint) TKNbalance;
    address TokenAddress = 0x1234567891234567891234567891234567891234;

    function approveTKN(uint256 _amount) external {
        IERC20(TokenAddress).approve(address(this), _amount);
    }

    function depositTKN(uint256 _amount) external {
        IERC20(TokenAddress).transferFrom(msg.sender, address(this), _amount);
        TKNbalance[msg.sender] += _amount;
    }

    function withdrawTKN(uint256 _amount) external {
        require(_amount <= TKNbalance[msg.sender], "!!! Not enough funds deposited !!!");
        IERC20(TokenAddress).transfer(msg.sender, _amount);
        TKNbalance[msg.sender] -= _amount;
    }

    function getTKNbalance() public view returns(uint) {
        return TKNbalance[msg.sender];
    }
}

I've tested like always in remix before writing my frontend. When I use my approveTKN function, it works, and the transaction is apparently a success. But when I call my allowance function in the token contract : Allowance error

No way to trasnfer anything. However, if I use directly the approve function in my token contract to allow the main contract to spend my tokens, it works, my allowance is increased by the value needed, and I can use the transfer function of my main contract...

It seems that I don't use correctly the approve function of the erc20 contract through the main contract...

I'm tearing my hair out...

1 Answers

You have to call approve first to set the mapping. this is allowance.:

function allowance(address _owner, address _spender) public override view returns (uint256 remaining){
        // you have to set this with calling approve
        return allowed[_owner][_spender];
    }

allowed is a mapping

  // my address is allowing your address for this much token
  mapping(address=>mapping(address=>uint256)) allowed;

You have to enter a property to allowed mapping first with approve function

function approve(address _spender, uint256 _value) public override returns (bool success){
        // add require logic here
        // it sets the mapping
        allowed[msg.sender][_spender]=_value;
        // if in the future there is a dispute, we can check those events for verification
        emit Approval(msg.sender,_spender,_value);
        return true;
    }
Related