Solidity - Atomic issue impossible to exchange USDT to another token?

I have this code :

 function buy_with_stablecoins(uint _tid, uint _amount) public { // _tid = 1 = usdt, _tid = 2 = usdc

        require(_tid == 1 || _tid ==2, "Invalid token id");
        require(presale_time>=block.timestamp, "Presale ended");


        // Calculate the amount of token to be sold.

        if(_tid ==1 ){

            require(usdt.allowance(msg.sender, address(this))>= _amount, "Does to have enough allownace to buy");
       
            uint _token_amount = (rate * _amount)/(10*6);

            total_sold += _token_amount;

            usdt.transferFrom(msg.sender, address(this), _amount);

            token.transfer(msg.sender, _token_amount);

        }else{

            require(usdc.allowance(msg.sender, address(this))>= _amount, "Does to have enough allownace to buy");
            uint _token_amount = (rate * _amount)/(10*6);

            total_sold += _token_amount;

            usdc.transferFrom(msg.sender, address(this), _amount);

            token.transfer(msg.sender, _token_amount);
        }

        _addParticipant(msg.sender);  // Register participant
    }

I don't know why it's not working it seems I have an error when I try to send USDT token to the presale contract the presale contract should send me my token contribution in exchange but not working...

1 Like

Please describe what's not working.

This description should by the least include:

  • The function that you are calling
  • The input values that you are passing to it
  • The code of every other function called internally
  • The value of every state (contract-level) variable involved
  • The error-message that you are getting

I have no error message and when I try to run the function it just make me an error since I add the code :

token.transfer(msg.sender, _token_amount);

I have already token in the presale contract so it should works I have for example no error with this function :

function buy_with_native_token() public payable { 

        require(presale_time>=block.timestamp, "Presale ended");

        uint _token_amount = (rate * msg.value * getETHPrice())/ (10**18 * 10**priceFeed.decimals());

        total_sold += _token_amount;
        token.transfer(msg.sender, _token_amount);

        _addParticipant(msg.sender);  // Register participant

    }

What part of this did you not understand?
The only thing which you have provided is the first bullet above.
Without all the rest, it is going to be rather difficult for anyone here to address the problem.
And yes, if you get an error, then there must be some sort of information indicating that an error has occurred (or you wouldn't be able to determine that it is indeed an error).

The original presale code :


contract Presale is Ownable{

    IERC20 public token;
    // Stablecoins
    IERC20 public usdt;
    IERC20 public usdc;

    uint public rate ; // 10 token per dollar.

    uint public total_sold  = 0; // to keep tract of total sold token.

    uint public presale_time = block.timestamp + 30 days;

    AggregatorV3Interface private priceFeed;

    mapping(address => bool) public participants;
    uint public numberOfParticipants = 0;  // New variable to keep track of number of participants


    constructor(address _token, address _usdt, address _usdc, uint _rate, address _priceFeedAddress){
        token = IERC20(_token);
        usdc = IERC20(_usdc);
        usdt = IERC20(_usdt);
        rate = _rate;
        priceFeed = AggregatorV3Interface(_priceFeedAddress);
    }

    function _addParticipant(address _participant) internal {
        if (!participants[_participant]) {
            participants[_participant] = true;
            numberOfParticipants++;  // Increase the count
        }
    }

    function buy_with_native_token() public payable { 

        require(presale_time>=block.timestamp, "Presale ended");

        uint _token_amount = (rate * msg.value * getETHPrice())/ (10**18 * 10**priceFeed.decimals());

        total_sold += _token_amount;
        token.transfer(msg.sender, _token_amount);

        _addParticipant(msg.sender);  // Register participant

    }

    function buy_with_stablecoins(uint _tid, uint _amount) public { // _tid = 1 = usdt, _tid = 2 = usdc

        require(_tid == 1 || _tid ==2, "Invalid token id");
        require(presale_time>=block.timestamp, "Presale ended");


        // Calculate the amount of token to be sold.

        if(_tid ==1 ){

            require(usdt.allowance(msg.sender, address(this))>= _amount, "Does to have enough allownace to buy");
            uint _token_amount = (rate * _amount)/ 10**usdt.decimals();

            total_sold += _token_amount;

            usdt.transferFrom(msg.sender, address(this), _amount);

            token.transfer(msg.sender, _token_amount);

        }else{

            require(usdc.allowance(msg.sender, address(this))>= _amount, "Does to have enough allownace to buy");
            uint _token_amount = (rate * _amount)/ 10**usdc.decimals();

            total_sold += _token_amount;

            usdc.transferFrom(msg.sender, address(this), _amount);

            token.transfer(msg.sender, _token_amount);
        }

        _addParticipant(msg.sender);  // Register participant
    }

    function set_presale(uint _rate,address _token, address _usdt, address _usdc) public onlyOwner{

        rate = _rate;

        token = IERC20(_token);
        usdt = IERC20(_usdt);
        usdc = IERC20(_usdc);

    }

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

    function getETHPrice() public view returns(uint) {
        (, int256 price, , , ) = priceFeed.latestRoundData();
        return uint256(price);
    }

    function withdraw() external onlyOwner {
        payable(owner()).transfer(address(this).balance);
    }

    function withdrawToken(address _add) external onlyOwner{
        IERC20(_add).transfer(msg.sender, IERC20(_add).balanceOf(address(this)));
    }

    function updatePresaleTime(uint _time) external onlyOwner {
        presale_time = block.timestamp + _time;
    }

}

For the token address I just specified a basic ERC20 token and I transfered 500 000 token to this contract. For the other address the official address of USDT and USDC and for getting price of ETH simply the chainlink price feed address. As I said before when I can buy with native token (in ETH) but not in USDT or USDC and I just have a metamask issue with high gas fee.