updated token
unknown
plain_text
a year ago
5.2 kB
3
Indexable
Never
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract SafeMoneyUp is ERC20, Ownable { uint256 private constant PRECISION = 1e18; uint256 private constant FIXED_SUPPLY = 400 * 1e12 * PRECISION; mapping(address => bool) public excludedFromFees; mapping(address => bool) public isBlacklisted; uint256 public adminFee = 50; // 0.5% (50/10000) constructor() ERC20("SafeMoney Up", "SMU") { _mint(address(this), FIXED_SUPPLY); excludedFromFees[owner()] = true; } ///@notice user can buy tokens by calling this function. ///@notice user shouldn't be blacklisted and smartcontract should have enough tokens to process his buy 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)); uint256 ethAmountInPool = address(this).balance; uint256 perTokenPrice = supplyWithoutContractAndBurn / ethAmountInPool; uint256 tokensToBuy = msg.value/perTokenPrice; require (balanceOf(address(this)) >= tokensToBuy, "not enough tokens in the pool"); uint256 fee = (msg.value * adminFee) / 10000; uint256 tokensWithFee = (tokensToBuy * 98) / 100; // 2% fee if (!excludedFromFees[msg.sender]) { tokensToBuy = tokensWithFee; require (balanceOf(address(this)) >= tokensToBuy, "not enough tokens in the pool"); (bool sent,) = owner().call{value: fee}(""); require(sent, "eth fees to admin failed"); } _transfer(address(this), msg.sender, tokensToBuy); } /// @param tokensToSell - number of tokens users want to sell. /// @notice user can call this function to sell his/her tokens. function sellTokens(uint256 tokensToSell) public { require(!isBlacklisted[msg.sender], "Address is blacklisted"); require(tokensToSell > 0, "Amount must be greater than 0"); uint256 supplyWithoutContractAndBurn = totalSupply() - balanceOf(address(this)) - balanceOf(address(0)); uint256 ethAmountInPool = address(this).balance; uint256 perTokenPrice = supplyWithoutContractAndBurn / ethAmountInPool; uint256 ethAmount = tokensToSell * perTokenPrice; require (address(this).balance >= ethAmount, "not enough eth in the pool"); uint256 fee = (tokensToSell * adminFee) / 10000; uint256 ethWithFee = (ethAmount * 98) / 100; // 2% fee _transfer(msg.sender, address(this), tokensToSell); if (!excludedFromFees[msg.sender]) { ethAmount = ethWithFee; require (address(this).balance >= ethAmount, "not enough eth in the pool"); _transfer (address(this), owner(), fee); //deduct fee in tokens } payable(msg.sender).transfer(ethAmount); } ///@param newAdminFee amount of fees in basis point ///@dev set admin fees, limited to 10 percent. function setAdminFee(uint256 newAdminFee) public onlyOwner { require(newAdminFee >= 0 && newAdminFee <= 1000, "Invalid fee value"); //max admin fee is 10 percent adminFee = newAdminFee; } ///@param account - user address ///@param excluded - boolean value ///@dev excluded or include someone from/in fees function excludeFromFees(address account, bool excluded) public onlyOwner { excludedFromFees[account] = excluded; } ///@param account - user address ///@param blacklisted - boolean value ///@dev manage blacklist of users using this function. function setBlacklistStatus(address account, bool blacklisted) public onlyOwner { isBlacklisted[account] = blacklisted; } /// @param tokensAmount - number of tokens to input /// @dev owner can add initial liquidity using this function (tokens and eth) function injectInitialLiquidity (uint256 tokensAmount) public onlyOwner payable { require (msg.value > 0, "eth amount should be greator than 0"); _transfer(msg.sender, address(this), tokensAmount); } /// @param - tokenAddress - address of ERC20 token /// @param - amount - amount to withdraw from smart contract /// @dev - owner can withdraw any ERC20 token using this function (except native token to avoid any rug pull function withdrawToken(address tokenAddress, uint256 amount) public onlyOwner { require(tokenAddress != address(this), "can't withdraw native token, no rug pull"); IERC20 token = IERC20(tokenAddress); uint256 tokenBalance = token.balanceOf(address(this)); require(amount <= tokenBalance, "Not enough tokens in contract"); token.transfer(owner(), amount); } /// @notice receive any external ether sent by user (except owner of this smartcontract) receive() external payable { require(msg.sender != owner(), "Owner cannot send Ether directly"); } }