Deposite and withdraw erc20 token using smart contract

my goal is to create a smart contract which allow users to deposit erc20 and withdraw erc20 token using smart contract .i tried to implement this functionality using token transfer and transferfrom functions and tried to send tokens to contract address .but its showing some error. i tried all the possible solution available on internet but no luck .please help me out

// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.10;

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 TestFunding
{

    mapping(address => uint) public users;

    address public owner;

    uint public minimumDeposit;

    uint public totalDeposit;

    uint public noOfUsers;

    constructor(){
        owner = msg.sender;
    }
    
    function depositToken(address _token,uint _amount) public {
        
         IERC20(_token).approve(address(this), _amount);
        IERC20(_token).transferFrom(msg.sender,address(this),_amount);
    }
    
       function depositToken2(address _token,uint _amount) public {

        IERC20(_token).transfer(address(this), _amount);
    }
    
    
    function getUserBalance() public view returns(uint)
    {
     return users[msg.sender];   
    }
    
    function getCurrentBalance(address _token) public view returns(uint)
    {
     return IERC20(_token).balanceOf(address(this)) ; 
    }
    
    function getTokenBalance(address _token,address _account) public view returns(uint)
    {
     return IERC20(_token).balanceOf(_account) ; 
    }
    
    
    
    function withdrawToken(address _token,uint _amount) public
    {
    
    IERC20(_token).approve(msg.sender, _amount);
    IERC20(_token).transferFrom(address(this),msg.sender,_amount);
    
    }
    
}

error 1 transferfrom function: transact to TestFunding.depositToken errored: VM error: revert.

revert The transaction has been reverted to the initial state. Reason provided by the contract: "ERC20: transfer amount exceeds allowance". Debug the transaction to get more information.

error 2 with transfer() function : transact to TestFunding.depositToken2 errored: VM error: revert.

revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.

The approve function is not used like this. The user has to call approve themselves, your smart contract can't do it for them. So once the user calls approve with the right amount and your contract address, then they invoke your contract which triggers transferFrom, at that point it has the right allowance so it will be able to perform the transfer.

thanks lot. now its working.concepts are cleared now

Hi Harish,
I have a very similar issue, however, I am not clear based on the comments above on solution.

I have a contract TOK which mints TOK tokens using openzeppelin ERC20, and assigns these to a 'custodian'.
Then I have another contract TOKCaller which uses TOK to transfer tokens to guests account which are neither custodian nor host account.

contract TOK is ERC20 {
    address public custodian;
    constructor() ERC20("TOK Token", "TOK") {
        custodian = msg.sender;
        _mint(custodian, 10000 * 10**18);
    }
}
contract TOKCaller is ERC20 {
     TOK public token;
     address public host;
     constructor(TOK _token) {
        token= _token;
        host = msg.sender;
     }

     depositToken1(address guest )  {
         token.transfer(guest, 1);
     }

     depositToken2(address guest )  {
         token.approve(guest, 1);
         token.transferFrom(token.custodian, guest, 1);
     }
}

Both of these result in errors "ERC20: transfer amount exceeds balance".

I am not clear when you say approve() cant be called by the contract, who can call approve(), as it is the method defined in ERC20 openzeppelin.

Any help is much appreciated.

Thanks!