Unable to transfer DAI token to Smart Contract on Ropsten Testnet using Metamask and Remix

The code below mentioned has the 3 methods which I'm trying to use to transfer DAI tokens (0xaD6D458402F60fD3Bd25163575031ACDce07538D) from my Metamask wallet to the Smart Contract.

In Method - 1: Some unnamed token is getting transferred but no DAI transfer (what is that unnamed token denoted by () why is it getting created?) .. the code is running fine and no errors are being thrown in this case.

In Method - 2: A gas estimation error is being thrown when I'm trying to use transferFrom to send DAI from my address to the Smart Contract.

In Method -3: TypeError: Member "_approve" not found or not visible after argument-dependent lookup in contract ERC20.

Need a correction or alternative way to send DAI or any other token for that matter, please.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// DAI - 0xaD6D458402F60fD3Bd25163575031ACDce07538D
 
import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";   
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

 contract DAI_txn {

    using SafeERC20 for ERC20;
    using SafeMath for uint256;

    ERC20 public token;
    uint public amount;

    uint public time;

    constructor(
        address _token
    ) {
        token = ERC20(_token);
        amount = 10;
    } 


    function deposit_DAI() public returns(bool) {

        bool success;
        address x = payable(msg.sender);

        // // Method - 1: DAI is not being transferred, some un-named token is getting transferred
        // (success, ) = payable(x).call(abi.encodePacked("token.transfer(address, uint256)", address(this), amount));

        // // Method - 2:Commented part throwing gas estimation error on remix
        // token.approve(address(this), amount * 2);
        // success = token.transferFrom(x, address(this), amount);

        // Method -3: 
        token._approve(x, address(this), amount);
        token.transferFrom(x, address(this), amount);

        return success;
    } 

    function balance() public view returns (uint) {
        return token.balanceOf(address(this));
    }

}

Hello @shush

It looks like you don't understand how ERC20 tokens work, and you should probably learn about that somewhere.

The TLDR is, it is not possible to transfer asserts from a user account to your contract without the user first approving the transfer. The user has to be the one approving... you can't just go see the contract and say "ho by the way, user X is ok with me taking their money"

So you need

  • one transaction, where the user calls approve on the token, allowing your contract to take the money
  • in another transaction, the user calls your contract, and your contract does a transferFrom, that takes the users funds.