ERC20 token swap/presale

I want to test a sale contract, that also takes ERC20 tokens and mint/burn another IERC20 token.

In this excample I try to implement USDT:

:computer: Environment
remix, robsten testnet

:memo:Details
So the sale contract should make it possible to swap USDT for the TestToken (the testToken has 18 decimals). Now when I call buy with 100 robsten USDT token metamask try to send 100 test ETH…

But I set with setInToken() the address of the inToken variable to the address of testnet USDT (0xFf48Ea739AeD20f3111042B38eCed6D999736fd3)

:1234: Code to reproduce

pragma solidity >=0.5.0 <0.8.0;


import "@openzeppelin/contracts/payment/PullPayment.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "./test.sol";

interface ERC20 {
    function balanceOf(address tokenOwner) external returns (uint balance);
    function allowance(address tokenOwner, address spender) external returns (uint remaining);
    function transfer(address to, uint tokens) external returns (bool success);
    function approve(address spender, uint tokens) external returns (bool success);
    function transferFrom(address from, address to, uint tokens) external returns (bool success);
    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}



contract AutomatedMarketMakerUSDT is PullPayment, Ownable{
    using SafeMath for uint256;
    // address _inToken; // ContractA Address
    mapping ( address => uint256 ) public balances;

    ERC20 private _inToken;
    TestToken private testToken;
    uint256 public _reserve;


    constructor() public {
    }

    receive () external payable {
    }

    function setInToken(address payable token) public onlyOwner{
        _inToken = ERC20(token);
    }

    function setToken(address payable token) public onlyOwner{
        testToken= TestToken(token);
    }

   
    function buy(uint256 amount) public payable{
        ERC20(_inToken).transferFrom(msg.sender, address(this), amount);
        testToken.mint(msg.sender, amount);
    }

    function sell(uint256 tokenAmount, uint256 usdtAmount) external{
        require(tokenAmount == usdtAmount.mul(10**12), 'The exchange ratio is 1:1');
        require(_inToken.balanceOf(address(this)) <= usdtAmount && testToken.totalSupply() <= usdtAmount, "Thats too much");
        uint256 newDecimalAmount = usdtAmount.div(10**6);
        ERC20(_inToken).transfer(msg.sender, newDecimalAmount);
        testToken.burn(msg.sender, tokenAmount);
    }
    
    function withdrawPayments(address payable payee) public override {
        // Do nothing
    }
}

The question(s):

How and why ERC20(_inToken).transferFrom(msg.sender, address(this), amount); is an call on ETH? And how can I make it run?

Thanks for them who knows the answere :slight_smile: (and write it)

1 Like

Hey, I think ERC20(_inToken).transferFrom(msg.sender, address(this), amount); can not call on ETH, what exactly does this is the keyword payable, cause Payable functions provide a mechanism to collect / receive funds in ethers to your contract, and it seems like you only need _inToken to buy testToken.

1 Like