Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
4.2 kB
8
Indexable
// SPDX-License-Identifier: MIT

pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";

contract SafeMoneyUp is ERC20, Ownable {
    using SafeMath for uint256;
    uint256 private constant PRECISION = 1e18;
    uint256 private constant FIXED_SUPPLY = 400 * 1e12 * PRECISION;

    mapping(address => bool) public excludedFromFees;
    mapping(address => bool) public isBlacklisted;
    uint256 private adminFeeTokens;

    uint256 public adminFee = 50; // 0.5% (50/10000)
     event tokenbought (uint256 eth, uint256 tokens);
     event tokenSold (uint eth, uint256 tokens);
    constructor() ERC20("SafeMoney Up", "SMU") {
        _mint(address(this), FIXED_SUPPLY);
        excludedFromFees[owner()] = true;
    }
   
    
    function buyTokens() public payable {
    require(!isBlacklisted[msg.sender], "Address is blacklisted");
    require(msg.value > 0, "Amount must be greater than 0");

    uint256 supplyWithoutContractAndBurn = totalSupply() - balanceOf(address(this)) - balanceOf(address(0)) - adminFeeTokens;

    uint256 ethAmountInPool = address(this).balance;
    uint256 perTokenPrice = supplyWithoutContractAndBurn.div(ethAmountInPool);
    uint256 tokensToBuy = msg.value.mul(perTokenPrice);
    
    if (!excludedFromFees[msg.sender]) {
        uint256 ethForAdmin = (msg.value * adminFee) / 10000;
        (bool sent,) = owner().call{value: ethForAdmin}("");
        require(sent, "eth fees to admin failed");
        tokensToBuy = (tokensToBuy * (1000 - 20))/1000;
    }

    _transfer(address(this), msg.sender, tokensToBuy);

    emit tokenbought (msg.value, tokensToBuy);
    } 


   function sellTokens(uint256 tokensToSell) public {
      require(!isBlacklisted[msg.sender], "Address is blacklisted");
      require(tokensToSell > 0, "Amount must be greater than 0");
       uint256 supplyWithoutContractAndBurn;
    if (totalSupply() > balanceOf(address(this)) + balanceOf(address(0))){
        supplyWithoutContractAndBurn = totalSupply() - balanceOf(address(this)) - balanceOf(address(0)) - adminFeeTokens;
    }else {
        supplyWithoutContractAndBurn = totalSupply();
    }

       uint256 ethAmountInPool = address(this).balance;
       uint256 perTokenPrice = supplyWithoutContractAndBurn.div(ethAmountInPool);
       uint256 ethAmount = tokensToSell.div(perTokenPrice);
      _transfer(msg.sender, address(this), tokensToSell);

      if (!excludedFromFees[msg.sender]) {
       
        uint256 ethWithFee = (ethAmount * (1000 - (20))) / 1000; 
        uint256 tokensForAdmin = (tokensToSell * adminFee) / 10000;

        ethAmount = ethWithFee;
        require (address(this).balance >= ethAmount, "not enough eth in the pool");
        _transfer (address(this), owner(), tokensForAdmin); //deduct fee in tokens
        adminFeeTokens += tokensForAdmin;
    } 
    (bool sent,) = msg.sender.call{value: ethAmount}("");
        require(sent, "eth fees to admin failed");

      emit tokenSold (ethAmount, tokensToSell);  
    }
     
    function setAdminFee(uint256 newAdminFee) public onlyOwner {
        require(newAdminFee >= 0 && newAdminFee <= 1000, "Invalid fee value"); //max admin fee is 10 percent
        adminFee = newAdminFee;
    }
    
    function excludeFromFees(address account, bool excluded) public onlyOwner {
        excludedFromFees[account] = excluded;
    }
    
    function setBlacklistStatus(address account, bool blacklisted) public onlyOwner {
        isBlacklisted[account] = blacklisted;
    }

    function injectInitialETHLiquidity () public onlyOwner payable {
        require (msg.value > 0, "eth amount should be greator than 0");
    }
    
    
    function withdrawToken (address token, uint256 amount) external onlyOwner {
        IERC20 TOKEN = IERC20(token);
        TOKEN.transfer(owner(), amount);
    }
   
  function withdrawETH (uint256 amount) external onlyOwner {
        (bool sent,) = owner().call{value: amount}("");
        require (sent, "eth transfer failed");
    }
    receive() external payable {
        require(msg.sender != owner(), "Owner cannot send Ether directly");
    }

    
}