// SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract PresaleToken is Ownable, ReentrancyGuard {
    IERC20 public token;
    address public from;
    uint256 private balance;
    uint256 public conversionRate;

    event Withdraw(address indexed wallet, uint256 amount, uint256 date);
    event Transfer(address indexed to, uint256 value);

    constructor(address _token, address _from, uint256 _conversionRate) {
        token = IERC20(_token);
        from = _from;
        conversionRate = _conversionRate;
    }

    function changeFromAddress(address _from) public onlyOwner {
        from = _from;
    }

    function changeConversionRate(uint256 _rate) public onlyOwner {
        conversionRate = _rate;
    }

    function checkBalance() public view onlyOwner returns(uint256) {
        return balance;
    }

    function transferTokens() public payable nonReentrant {
        address _to = msg.sender;
        require(_to != address(0), "Non zero address required");
        require(msg.value != 0, "More than 0 eth required");
        balance = balance + msg.value;
        uint256 tokensToSend = msg.value * conversionRate;
        token.transferFrom(from, _to, tokensToSend);
        emit Transfer(_to, tokensToSend);
    }

    function withDrawEth() public onlyOwner {
        (bool os, ) = payable(msg.sender).call{value: balance}("");
        require(os, "Withdraw not Successful!");
        emit Withdraw(msg.sender, balance, block.timestamp);
    }
}
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_conversionRate","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"date","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"changeConversionRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"}],"name":"changeFromAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"conversionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"from","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withDrawEth","outputs":[],"stateMutability":"nonpayable","type":"function"}]