Skip to content

Instantly share code, notes, and snippets.

@coderwithsense
Created January 4, 2024 10:53
Show Gist options
  • Save coderwithsense/288e9418e6f90ce1c664cdfce809ade7 to your computer and use it in GitHub Desktop.
Save coderwithsense/288e9418e6f90ce1c664cdfce809ade7 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.23+commit.f704f362.js&optimize=false&runs=200&gist=
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
interface IUniswapV2Factory {
function createPair(address tokenA, address tokenB)
external
returns (address pair);
}
interface IUniswapV2Router02 {
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidityETH(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
)
external
payable
returns (
uint256 amountToken,
uint256 amountETH,
uint256 liquidity
);
}
contract cryptoGradTaxToken is ERC20, ERC20Permit, Ownable {
using SafeMath for uint256;
mapping(address => bool) private _buyerMap;
mapping(address => bool) private _bots;
mapping(address => uint256) private _holderLastTransferTimestamp;
mapping(address => bool) private _excludedFromFee;
address payable private _taxWallet;
address public _marketingWallet;
address public _devWallet;
address public _cexWallet;
uint256 private _buyTax = 30;
uint256 private _sellTax = 40;
uint256 private _finalBuyTax = 5;
uint256 private _finalSellTax = 5;
uint256 private _reduceBuyTaxAt = 56;
uint256 private _reduceSellTaxAt = 56;
uint256 private _preventSwapBefore = 20;
uint256 public _buyCount = 0;
uint256 public tradingStartedTime;
uint8 private constant _decimals = 18;
uint256 private constant _totalSupply = 100000000 * 10 ** _decimals; // 100 million
uint256 public _maxTransaction = (_totalSupply * 3) / 100; // 3% of total supply
uint256 public _maxWalletSize = (_totalSupply * 2) / 100; // 2% of total supply
uint256 public _taxSwapThreshold = _totalSupply * 5 / 1000; // 0.5% of total supply
uint256 public _maxTaxSwap = _totalSupply / 1000; // 0.1% of total supply
IUniswapV2Router02 private uniswapV2Router;
address private uniswapV2Pair;
bool public tradingOpen = false;
bool private inSwap = false;
bool private swappingOn = false;
event MaxTxAmountUpdated(uint _maxTransaction);
modifier lockTheSwap {
inSwap = true;
_;
inSwap = false;
}
// inital mint: dev(5%), marketing(2.5%), cex(2.5%), owner(90%)
constructor (address marketingWallet, address cexWallet, address devWallet) ERC20("Crypto Grad Token", "CGT") ERC20Permit("Crypto Grad Token") Ownable(_msgSender()){
_devWallet = devWallet;
_marketingWallet = marketingWallet;
_cexWallet = cexWallet;
_taxWallet = payable(msg.sender);
uint256 _supplyInGwei = _totalSupply * 10 ** decimals();
_mint(msg.sender, _supplyInGwei * 90 / 100);
_mint(_devWallet, _supplyInGwei * 5 / 100);
_mint(_marketingWallet, _supplyInGwei * 25 / 1000);
_mint(_cexWallet, _supplyInGwei * 25 / 1000);
// set owner, contract address, tax wallet, marketing wallet, cex wallet, dex wallet excluded from fees on buy/sell
_excludedFromFee[owner()] = true;
_excludedFromFee[address(this)] = true;
_excludedFromFee[_taxWallet] = true;
_excludedFromFee[_marketingWallet] = true;
_excludedFromFee[_cexWallet] = true;
_excludedFromFee[_devWallet] = true;
}
// overriding _transfer function
function _transfer(address from, address to, uint256 value) internal override {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
require(value > 0, "Transfer amount must be greater than zero");
uint256 finalTaxAmountOnTransaction = 0;
(uint256 _taxOnBuy, uint256 _taxOnSell) = getCurrentTax();
if (from != owner() && to != owner()) {
require(!_bots[from] && !_bots[to], "Bots not allowed to buy");
if (from == uniswapV2Pair && to != address(uniswapV2Router) && !_excludedFromFee[to]) {
require(value <= _maxTransaction, "Exceed Max transaction amount");
require(balanceOf(to) + value <= _maxWalletSize, "Exceeds the maxWalletSize.");
if (_buyCount < _preventSwapBefore) {
require(!isContract(to), "Not allow contract buy now");
}
_buyCount++;
_buyerMap[to] = true;
}
// Tax on buy
finalTaxAmountOnTransaction = value.mul(_taxOnBuy).div(100);
if (to == uniswapV2Pair && from != address(this)) {
require(value <= _maxTransaction, "Exceed Max transaction amount.");
// Tax on sell
finalTaxAmountOnTransaction = value.mul(_taxOnSell).div(100);
require(_buyCount > _preventSwapBefore || _buyerMap[from], "Seller is not buyer");
}
uint256 contractTokenBalance = balanceOf(address(this));
if (!inSwap && to == uniswapV2Pair && swappingOn && contractTokenBalance > _taxSwapThreshold && _buyCount > _preventSwapBefore) {
swapTokensForEth(minOfTwo(value, minOfTwo(contractTokenBalance, _maxTaxSwap)));
uint256 ethBalance = address(this).balance;
if (ethBalance > 0) {
sendETHToFee(address(this).balance);
}
}
}
// add liquidity dont charge fee
if (_excludedFromFee[to] && to == address(uniswapV2Pair)) {
finalTaxAmountOnTransaction = 0;
}
// no fee when transfer
if(from != address(uniswapV2Pair) && to != address(uniswapV2Pair)) {
finalTaxAmountOnTransaction = 0;
}
if (finalTaxAmountOnTransaction > 0) {
// _balances[address(this)] = _balances[address(this)].add(finalTaxAmountOnTransaction);
_update(from, address(this), finalTaxAmountOnTransaction);
// emit Transfer(from, address(this), finalTaxAmountOnTransaction);
}
// _balances[from] = _balances[from].sub(value);
// _balances[to] = _balances[to].add(value.sub(finalTaxAmountOnTransaction));
_update(from, to, value - finalTaxAmountOnTransaction);
// emit Transfer(from, to, value.sub(finalTaxAmountOnTransaction));
}
// function to return the smart contract address for UNI-V2 pair token
function getTradingPairTokenContract() public view returns(address) {
require(tradingOpen, "Trading not started yet");
return address(uniswapV2Router);
}
// function to send eth to the (private function)
function sendETHToFee(uint256 amount) private {
_taxWallet.transfer(amount);
}
// function to check if the account address is a bot
function isBot(address a) public view returns (bool){
return _bots[a];
}
// function to set the account as a bot
function setAccountAsBot(address addr) public {
_bots[addr] = true;
}
// function create a liquidity pool on uniswap (WETH/Token), and set the tradingOpen to true
function createPoolStartTrading() external onlyOwner() {
require(!tradingOpen, "Trading already set to true");
uniswapV2Router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
_approve(address(this), address(uniswapV2Router), _totalSupply);
uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(address(this), uniswapV2Router.WETH());
_excludedFromFee[address(uniswapV2Pair)] = true;
uniswapV2Router.addLiquidityETH{value: address(this).balance}(address(this), balanceOf(address(this)), 0, 0, owner(), block.timestamp);
IERC20(uniswapV2Pair).approve(address(uniswapV2Router), type(uint).max);
_excludedFromFee[address(uniswapV2Pair)] = false;
tradingOpen = true;
swappingOn = true;
tradingStartedTime = block.timestamp;
}
// function to return the current contract (private function)
function isContract(address account) private view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
// function for manualSwapping of tokens to eth in the address
function manualSwap() external {
require(_msgSender() == _taxWallet);
uint256 tokenBalance = balanceOf(address(this));
if (tokenBalance > 0) {
swapTokensForEth(tokenBalance);
}
uint256 ethBalance = address(this).balance;
if (ethBalance > 0) {
sendETHToFee(ethBalance);
}
}
// funciton for returning current buy/sell tax
function getCurrentTax() private view returns (uint, uint) {
// buy/sell within 3 minutes of starting the trade (returns initial taxes)
if (tradingStartedTime + 60 * 3 > block.timestamp) {
return (_buyTax, _sellTax);
}
// buy/sell within 3 minutes to 11 minutes of starting the trade (returns 20% buy/sell tax)
else if (tradingStartedTime + 60 * 3 < block.timestamp && block.timestamp < tradingStartedTime + 60 * 11) {
return (20, 20);
// buy/sell within 11 minutes to 20 minutes of starting the trade (returns 10% buy/sell tax)
} else if (tradingStartedTime + 60 * 11 < block.timestamp && block.timestamp < tradingStartedTime + 60 * 20) {
return (10, 10);
// buy/sell tax after 20 minutes of trading start (final buy/sell tax)
} else if (block.timestamp > tradingStartedTime + 60 * 20) {
return (_finalBuyTax, _finalSellTax);
}
}
// function for setting maxTransaction back to default
function maxTransactionToDefault() external onlyOwner() {
_maxTransaction = _totalSupply.div(100);
emit MaxTxAmountUpdated(_maxTransaction);
}
// function for returning minimum of two numbers (private function)
function minOfTwo(uint256 numberA, uint256 numberB) private pure returns (uint256){
return (numberA > numberB) ? numberB : numberA;
}
// function to swap tokens for eth (private function)
function swapTokensForEth(uint256 tokenAmount) private lockTheSwap {
if (tokenAmount == 0) {return;}
if (!tradingOpen) {return;}
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = uniswapV2Router.WETH();
_approve(address(this), address(uniswapV2Router), tokenAmount);
uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount,
0,
path,
address(this),
block.timestamp
);
}
// function for receiving eth in the contract
receive() external payable {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment