How can I protect my token from whales?

How can I protect my token from whales? Max wallet? Max tx? Or does anyone know of alternative solutions?

pragma solidity ^0.8.7;
interface IERC20 {
    function transfer(address _to, uint256 _amount) external returns (bool);

contract AntiWhaleFinance {
    string public constant _name = "AntiWhaleFinance";
    string public constant _symbol = "AWF";
    uint8 public constant _decimals = 18;
    uint256 public constant _totalSupply = 36000000 * 10**_decimals;        
    mapping (address => uint256) private balances;
    mapping (address => mapping (address => uint256)) private allowances;

    address public _owner = address(0);

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    constructor () {
        emit OwnershipTransferred(_owner, msg.sender);
        emit Transfer(address(0), msg.sender, _totalSupply);
        _owner = msg.sender;
        balances[_owner] = _totalSupply;
    receive () external payable {}
    modifier onlyOwner() {
        require(_owner == msg.sender, "Error: caller is not the owner");

    function name() public view returns (string memory) {
        return _name;
    function symbol() public view returns (string memory) {
        return _symbol;
    function decimals() public view returns (uint8) {
        return _decimals;
    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    function getOwner() public view returns (address) {
        return _owner;
    function balanceOf(address account) public view returns (uint256) {
        return balances[account];
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "Error: transfer from the zero address");
        require(recipient != address(0), "Error: transfer to the zero address");

        uint256 senderBalance = balances[sender];
        require(senderBalance >= amount, "Error: transfer amount exceeds balance");
        balances[sender] = senderBalance - amount;
        balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "Error: approve from the zero address");
        require(spender != address(0), "Error: approve to the zero address");

        allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    function transfer(address recipient, uint256 amount) public virtual returns (bool) {
        _transfer(msg.sender, recipient, amount);
        return true;
    function transferFrom(address sender, address recipient, uint256 amount) public virtual returns (bool) {
        uint256 currentAllowance = allowances[sender][msg.sender];
        require(currentAllowance >= amount, "Error: transfer amount exceeds allowance");
        _transfer(sender, recipient, amount);
        _approve(sender, msg.sender, currentAllowance - amount);
        return true;

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        _approve(msg.sender, spender, amount);
        return true;
    function allowance(address owner, address spender) public view virtual returns (uint256) {
        return allowances[owner][spender];
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(msg.sender, spender, allowances[msg.sender][spender] + addedValue);
        return true;
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = allowances[msg.sender][spender];
        require(currentAllowance >= subtractedValue, "Error: decreased allowance below zero");
        _approve(msg.sender, spender, currentAllowance - subtractedValue);
        return true;
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Error: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
1 Like

Hi @organik,
Thanks for posting. Can you say more about the specific kinds of interactions you would like to protect against? Do you want to limit how many tokens can be owned by a given address?

Thanks for your help. @slw.eth Yup. For example max holder 5%. Can we produce a function that can do this limitation before the transaction occurs? So what I mean is: Someone wanted to trade 6% and instant alert. I want him not to have to pay gas fees. Is this possible?

you can use max tx and max wallet, so many token out there using that function just surf the bscscan or telegram for that, the max tx will gives an error when buyer buy above limits.

@pytune thanks for your reply :blush:

I've been surfing telegram and bscscan for a week. I came across a few examples and even tried them all on testnet.

I arrived at such a partial solution :frowning: I added them to the transfer function :

 uint256 public _maxWalletToken = 18 * 10**5 * 10**18;
 uint256 public _maxTxAmount    = 9 * 10**5 * 10**18;

require(balances[recipient] + amount <= _maxWalletToken, "Exceeds maximum wallet token amount (1,800,000)");
require(amount <= _maxTxAmount, "TX Limit Exceeded");

For example, the max wallet is 5%.
I have one question. More precisely, a few problems:

  • User pays gas fee when sending to another wallet and then the transaction fails. I want the transaction not allowed at no cost. Only with warning.
  • I tried adding liquidity to the pancakeswap testnet and making purchases exceeding the max wallet amount. And also on sale. It just gave a warning and I didn't pay. This is nice. I'm wondering if there is a problem with the mainnet? For example, I am afraid that after adding liquidity, the balance in the pancakeswap contract will be more than 5% so no one will be able to sell.

I would appreciate your help as I am not an expert on Solidity. Best regards

I would appreciate it if someone who really knows the job could help. Or at least tell me I'm on the right or wrong track. Maybe it's a silly request, but at least give me peace of mind.

You can set it up as a require statement in all your transfer functions , so your users don't have to pay gas fees.

You can also make an exception list like the token creator and exchange pair address don't have to observe that

1 Like

@organik gas fee is always paid for write function whether is successful or not. But there are 2solutions to your project. One is dapp like pancakeswap platform or you use pure function to check the condition first and fire the transfer event if condition is met

Pls can anyone help me with the code to replace with the Max wallet transaction function? Am try to launch a fair launch token where everyone will have equal purchase limit. For example highest purchase limit should be 1% and Max wallet also should be 1% .