Solved! Unable To Withdraw Liquidity From My Token

Context

Hi all, I used Remix to deploy a contract following a pretty standard template (with IDEXROUTER and a DividendDistributor).

I added liquidity, trading started, everything went smoothly, fees were correct and autoSwap worked properly to claim BNB for marketing wallet. Now people are no longer holding/trading, so I want to remove liquidity.

The Problem:
When I try to remove liquidity on pancakeswap, upon clicking "Enable" and then "Remove", nothing happens. I've added/removed liquidity both on testnet and mainnet before so I'm pretty confident I'm doing the correct steps.

When clicking Remove, in the developer console I get:

MetaMask - RPC Error: Internal JSON-RPC error <debugging code>
estimateGas failed removeLiquidityETHWithPermit <debugging code>
MetaMask - RPC Error: Internal JSON-RPC error <debugging code>
estimateGas failed removeLiquidityETHWithPermitSupportingFeeOnTransferTokens <debugging code>
This transaction would fail. Please contact support.

What I've tried:
I have tried clicking "receive WBNB instead". No effect.
I have tried setting liquidity slippage to 49% before removing. No effect.
I have tried setting swapAndLiquify to false. No effect. edit: this might have been necessary. Not sure.
I have tried removing a small amount of liquidity. The most I could remove at once was -- i actually solved my problem while trying to find a precise amount for this part 0.0033LP, or 1,000,000 tokens and 0.014BNB.

My Code

pragma solidity ^0.7.2;

library Address { <standard implementation> }
abstract contract Context { <standard implementation> }
library SafeMath { <standard implementation> }
interface IERC20 { <standard functions> }
contract Ownable is Context { <standard implementation> }
interface IDEXFactory { < standard createPair >}
interface IDEXRouter { < addLiquidity and Swap functions, but no removeLiquidity > }
interface IDividendDistributor { <standard functions> }
contract DividendDistributor is IDividendDistributor { <code to distribute AVAX to holders> }


contract <token name> is IERC20, Ownable {
    using SafeMath for uint256;

    address AVAX = 0x1CE0c2827e2eF14D5C4f29a091d735A204794041;
    address WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
    address DEAD = 0x000000000000000000000000000000000000dEaD;
    address ZERO = 0x0000000000000000000000000000000000000000;

    string constant _name = "<token name>"; 
    string constant _symbol = "<token symbol>";
    uint8 constant _decimals = 9;

    uint256 _totalSupply = 100000000 * (10 ** _decimals);        // 100,000,000
    uint256 public _maxTxAmount = (_totalSupply * 1) / 100;    // 1% of Total Supply.
    uint256 public _maxWalletSize = (_totalSupply * 2) / 100;   // 2% of Total Supply

    mapping (address => uint256) _balances;
    mapping (address => mapping (address => uint256)) _allowances;

    mapping (address => bool) isFeeExempt;
    mapping (address => bool) isTxLimitExempt;
    mapping (address => bool) isDividendExempt;

    uint256 liquidityFee = 300; // 3%
    uint256 marketingFee = 400;  // 4%
    uint256 totalFee = 700; // liquidityFee + reflectionFee + marketingFee
    uint256 feeDenominator = 10000;
    
   <some irrelevant code omitted for brevity>

    IDEXRouter public router;
    address public pair;

    bool public autoBuybackEnabled = false;
    DividendDistributor distributor;
    uint256 distributorGas = 500000;

    bool public swapEnabled = true;
    uint256 public swapThreshold = _totalSupply / 100; // 1%

    constructor () {
        router = IDEXRouter(0x10ED43C718714eb63d5aA57B78B54704E256024E);
        pair = IDEXFactory(router.factory()).createPair(WBNB, address(this));
        _allowances[address(this)][address(router)] = uint256(-1);

        distributor = new DividendDistributor(address(router));

        setFees();
        setExemptions();
        autoLiquidityReceiver = address(0x000000000000000000000000000000000000dEaD);
        marketingFeeReceiver = address(< my marketing wallet >);

        _balances[msg.sender] = _totalSupply;
        emit Transfer(address(0), msg.sender, _totalSupply);
    }

The solution

I noticed that while withdrawing liquidity, the most I could withdraw was exactly 1,000,000 tokens. Which happened to be the _maxTxAmount. So the issue was that I could not withdraw more than the maxTxAmount of tokens. I Fixed this by calling my contract's setTxLimit with 10,000,000,000,000,000,000 which sets _maxTxAmount to the max supply (100,000,000). Then I withdrew 100% of the liquidity without any problems. (this requires having ownership of the contract)

Notes: My wallet is both the deployer and the owner, so it should be exempt from limits. Not sure why this caused a problem. My best guess is that pancakeswap router was not exempt from txLimit and so it couldn't send me the full amount of tokens.

Also, I tried doing this once before and it didn't work. For some reason, the setTxLimit function was like this:
function setTxLimit(uint256 amount) external onlyOwner { _maxTxAmount = amount.div(100); }
Idk why it divides amount by 100. I just multiplied amount by 100 to cancel it out, and got a result of 10,000,000,000,000,000,000. Upon passing that to setTxLimit, everything was fixed.

1 Like