Any suggestion about my first ERC20 token with fee

Hello Everyone, this is my first code and i searching for any kind of tip to make it better. If anyone want to make any suggestion i will be very grateful and one more thing, i have a little difficult to decide what is the best form to do a ICO. Someone have any experience on the matter?

address private _owner;
address private _previousOwner;
address payable public _charityWalletAddress;
address payable public _mktWalletAddress;
address payable public _devWalletAddress;


mapping (address => uint256) private _balances;
mapping (address => bool) private _isExcludedFromFee;
mapping (address => mapping(address => uint256)) private _allowances;

uint256 private _totalSupply = 1000000000*10**9;

//Marketing Fee = _mktFee/1000
//Charity Fee = _charityFee/1000
//Jujuba Team Development Fee = devFee/1000

uint256 public _mktFee = 0;
uint256 public _charityFee = 0;
uint256 public _devFee = 0;
uint256 private _totalFeeAmount;
uint256 private charityFeeAmount;
uint256 private mktFeeAmount;
uint256 private devFeeAmount;
uint256 public _tokenHavingsLimit;
uint256 private _possibleAmountTransfer;
uint256 public _totalBurnedLpTokens;

bool private _paused;

IPancakeswapV2Router02 public immutable PancakeswapV2Router;
address public immutable PancakeswapV2Pair;


constructor() ERC20("Jujuba", "JUJU") {
    
    _mint(_msgSender(), _totalSupply);
    
    IPancakeswapV2Router02 _PancakeswapV2Router = IPancakeswapV2Router02(0xD99D1c33F9fC3444f8101754aBC46c52416550D1);
     // Create a Pancakeswap pair for this new token
    PancakeswapV2Pair = IPancakeswapV2Factory(_PancakeswapV2Router.factory())
        .createPair(address(this), _PancakeswapV2Router.WETH());
    // set the rest of the contract variables
    PancakeswapV2Router = _PancakeswapV2Router;
    //exclude owner and this contract from fee
    _isExcludedFromFee[owner()] = true;
    _isExcludedFromFee[address(this)] = true;
    
    
    _paused = false;
    
    _balances[_msgSender()] = _totalSupply;
    
// Exclude owner and this contract from fee
    _isExcludedFromFee[_msgSender()] = true;
    _isExcludedFromFee[address(this)] = true;
    
    address msgSender = _msgSender();
    _owner = msgSender; 
    
    emit Transfer(address(0), address(this), _totalSupply);
    emit OwnershipTransferred(address(0), msgSender);
  }

modifier whenNotPaused() virtual override {
    require(!paused(), "Pausable: paused");
    _;
}
 
modifier whenPaused() virtual override {
    require(paused(), "Pausable: not paused");
    _;
 }

function totalSupply() public view virtual override returns (uint256) {
    return _totalSupply;
 }

function _pause() public virtual override whenNotPaused onlyOwner {
    _paused = true;
    emit Paused(_msgSender());
}

function _unpause() public virtual override whenPaused onlyOwner {
    _paused = false;
    emit Unpaused(_msgSender());
}

 function paused() public view virtual override returns (bool) {
    return _paused;
 }
    
function owner() public view override virtual returns (address) {
    return _owner;    
 }    

 modifier onlyOwner() virtual override{
    require(owner() == _msgSender(), "Ownable: caller is not the owner");
    _;
}  
    
function renounceOwnership() public override virtual onlyOwner {
    emit OwnershipTransferred(_owner, address(0));
    _owner = address(0);
}
    
function transferOwnership(address newOwner) public override virtual onlyOwner {
    require(newOwner != address(0), "Ownable: new owner is the zero address");
    emit OwnershipTransferred(_owner, newOwner);
    _owner = newOwner;
}

function currentCharityFee() public view returns (uint256) {
        return _charityFee;
 }
 
 function currentmktFee() public view returns (uint256) {
        return _mktFee;
    } 
    
function currentdevFee() public view returns (uint256) {
        return _devFee;
    }    

function balanceOf(address account) public view virtual override returns(uint256) {
    return _balances[account];
}

function _transfer(address recipient, uint256 amount) public whenNotPaused returns (bool success) {
    require(balanceOf(_msgSender()) >= amount, 'balance is too low');
    require(_getPossibleAmountTransfer(_tokenHavingsLimit, recipient) >= amount, 'amount makes balance surpass the limit');
    if(_isExcludedFromFee[_msgSender()] && _isExcludedFromFee[recipient]) {
        _balances[recipient] += amount;
        _balances[_msgSender()] -= amount;
    emit Transfer(_msgSender(), recipient, amount);
    return true;
    
    } else if(!_isExcludedFromFee[_msgSender()] || !_isExcludedFromFee[recipient]) {
        _totalFeeAmount = _getFeesAmount(amount, _charityFee, _mktFee, _devFee);
        uint256 amountToTransfer = amount.sub(_totalFeeAmount);
        _balances[recipient] += amountToTransfer;
        _balances[_msgSender()] -= amount;
        _transferToFeeWallet();
     emit Transfer(_msgSender(), recipient, amountToTransfer);
     return true;
     }
    
 }

function increaseAllowance(address sender, uint256 addedAmount) public override returns (bool) {
    _approve(_msgSender(), sender, _allowances[_msgSender()][sender] + addedAmount);
    return true;
}

function decreaseAllowance(address sender, uint256 subtractedAmount) public override returns (bool) {
    uint256 currentAllowance = _allowances[_msgSender()][sender];
    require(currentAllowance >= subtractedAmount, "Jujuba: decreased allowance below zero");
    _approve(_msgSender(), sender, currentAllowance - subtractedAmount);

    return true;
}

function transferFrom(address sender, address recipient, uint256 amount) public whenNotPaused override returns (bool succeess) {

    
    uint256 currentAllowance = _allowances[sender][_msgSender()];
    require(currentAllowance >= amount, "Jujuba: Transfer amount exceeds allowance");
    require(balanceOf(sender) >= amount, 'balance is too low');
    require(_getPossibleAmountTransfer(_tokenHavingsLimit, recipient) >= amount, 'amount makes balance surpass the limit');
    if(_isExcludedFromFee[_msgSender()] && _isExcludedFromFee[recipient]) {
        _balances[recipient] += amount;
        _balances[sender] -= amount;
    emit Transfer(sender, recipient, amount);
    return true;
    
    } else if(!_isExcludedFromFee[_msgSender()] || !_isExcludedFromFee[recipient]) {
        _totalFeeAmount = _getFeesAmount(amount, _charityFee, _mktFee, _devFee);
        uint256 amountToTransfer = amount.sub(_totalFeeAmount);
        _balances[recipient] += amountToTransfer;
        _balances[sender] -= amount;
        _transferToFeeWallet();
        _approve(sender, _msgSender(), currentAllowance - amount);
     emit Transfer(sender, recipient, amountToTransfer);
     return true;
  
    }
}

function approve(address spender, uint256 amount) public override returns (bool) {
    _approve(_msgSender(), spender, amount);
    return true;
}


function _approve(address sender, address spender, uint256 amount) internal virtual override {
    require(sender != address(0), "ERC20: approve from the zero address");
    require(spender != address(0), "ERC20: approve to the zero address");

    _allowances[sender][spender] = amount;
    emit Approval(sender, spender, amount);
}

function setExcludeFromFee(address account, bool) external onlyOwner() {
        _isExcludedFromFee[account] = true;
    }

function isExcludedFromFee(address account) public view returns(bool) {
        return _isExcludedFromFee[account];
    }
    
function _setCharityFee(uint256 charityFee) external onlyOwner() {
    require(charityFee >= 0 && charityFee <= 10, "CharityFee should be in 0 - 10 range");
        _charityFee = charityFee;
    }
    
function _setCharityWallet(address payable charityWalletAddress) external onlyOwner() {
        _charityWalletAddress = charityWalletAddress;
    }
    
function _setMktFee(uint256 mktFee) external onlyOwner() {
    require(mktFee >= 0 && mktFee <= 10, "MktFee should be in 0 - 10 range");
        _mktFee = mktFee;
    }
    
function _setMktWallet(address payable mktWalletAddress) external onlyOwner() {
        _mktWalletAddress = mktWalletAddress;
    }

function _setDevFee(uint256 devFee) external onlyOwner() {
    require(devFee >= 0 && devFee <= 10, "DevFee should be in 0 - 10 range");
        _devFee = devFee;
    }
    
function _setDevWallet(address payable devWalletAddress) external onlyOwner() {
        _devWalletAddress = devWalletAddress;
    }

function _setTokenHavingsLimit(uint256 tokenHavingsLimit) external onlyOwner() {
        _tokenHavingsLimit = tokenHavingsLimit;
    }

function _getFeesAmount(uint256 amount, uint256 charityFee, uint256 mktFee, uint256 devFee) private returns(uint256) {
   charityFeeAmount = amount.mul(charityFee).div(1000);
   mktFeeAmount = amount.mul(mktFee).div(1000);
   devFeeAmount = amount.mul(devFee).div(1000);
   _totalFeeAmount = _totalFeeAmount.add(charityFeeAmount).add(mktFeeAmount).add(devFeeAmount);
   return (_totalFeeAmount);
}

function _getPossibleAmountTransfer(uint256 tokenHavingsLimit, address recipient) private returns(uint256) {
   _possibleAmountTransfer = tokenHavingsLimit.sub(_balances[recipient]);
   return (_possibleAmountTransfer);
}

function _transferToFeeWallet() private returns (bool) {
   _balances[_charityWalletAddress] += charityFeeAmount;
   _balances[_mktWalletAddress] += mktFeeAmount;
   _balances[_devWalletAddress] += devFeeAmount;
   return true;
}

receive() external payable {}
  }

Hi, welcome! :wave:

It seems like the code you shared above is your ERC20 token, it does not contain a function to buy this token.
And I think you are looking for a Crowdsale contract, maybe you can have a look at this:

1 Like