Untitled

 avatar
unknown
plain_text
2 years ago
3.7 kB
5
Indexable
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.18;

import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.0/contracts/token/ERC20/IERC20.sol";
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.0/contracts/token/ERC20/ERC20.sol";
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.0/contracts/access/Ownable.sol";
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.0/contracts/security/ReentrancyGuard.sol";
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.0/contracts/security/Pausable.sol";

contract SafeMoneyUp is ERC20, Ownable, ReentrancyGuard, Pausable {
    uint256 private constant FIXED_SUPPLY = 400 * 1e6 * 1e18;
    address private constant DEAD_ADDRESS = 0x000000000000000000000000000000000000dEaD;

    mapping(address => bool) public excludedFromFees;

    event TokensPurchased(address indexed buyer, uint256 tokensAmount, uint256 ethAmount);
    event TokensSold(address indexed seller, uint256 tokensAmount, uint256 ethAmount);

    constructor() ERC20("SafeMoney Up", "SMU") {
        _mint(address(this), FIXED_SUPPLY);
        excludedFromFees[owner()] = true;
    }

    function getPrice() public view returns (uint256) {
        uint256 contractEthBalance = address(this).balance;
        uint256 supplyWithoutContract = totalSupply() - balanceOf(address(this)) - balanceOf(DEAD_ADDRESS);
        uint256 price = contractEthBalance * 1e18 / supplyWithoutContract;
        return price;
    }

    function buyTokens() public payable whenNotPaused nonReentrant {
        require(msg.value > 0, "Amount must be greater than 0");

        uint256 price = getPrice();
        uint256 tokensToBuy = msg.value * 1e18 / price;

        uint256 fee = tokensToBuy * 2 / 100;
        uint256 tokensWithFee = tokensToBuy - fee;

        if (!excludedFromFees[msg.sender]) {
            tokensToBuy = tokensWithFee;
        }

        _transfer(address(this), msg.sender, tokensToBuy);
        emit TokensPurchased(msg.sender, tokensToBuy, msg.value);
    }

     function sellTokens(uint256 tokensToSell) public whenNotPaused nonReentrant {
        require(tokensToSell > 0, "Amount must be greater than 0");

        uint256 price = getPrice();
        uint256 ethAmount = tokensToSell * price / 1e18;

        uint256 fee = ethAmount * 2 / 100;
        uint256 ethWithFee = ethAmount - fee;

        if (!excludedFromFees[msg.sender]) {
            ethAmount = ethWithFee;
        }

        _transfer(msg.sender, address(this), tokensToSell);
        payable(msg.sender).transfer(ethAmount);
        emit TokensSold(msg.sender, tokensToSell, ethAmount);
    }

    function excludeFromFees(address account, bool excluded) public onlyOwner {
        require(account != address(0), "Invalid address");
        excludedFromFees[account] = excluded;
    }

    function withdrawTokens(IERC20 token, uint256 amount) public onlyOwner {
        require(address(token) != address(0), "Invalid token address");
        token.transfer(msg.sender, amount);
    }

    function transferEthToContract() public payable onlyOwner {
        require(msg.value > 0, "Amount must be greater than 0");
    }

    function pause() public onlyOwner {
        _pause();
    }

    function unpause() public onlyOwner {
        _unpause();
    }

    function receiveETH() external payable {
    }
    function withdrawETH(uint256 amount) public onlyOwner {
    require(amount <= address(this).balance, "Insufficient contract balance");
    payable(owner()).transfer(amount);
}

}