Simple algorithmic semi-stable coin transfer failure

I am coding a token where you can give the token price a range to be traded in.
Example: Initial token price is $10, range is $5. Token price can go as high as $15 and as low as $5

After each buy or sell, I call a function internally to check the reserves of the liquidity pair to calculate the price after the trade to see if a buyback or sell is needed to bring the price back into range.

This works perfectly when I test in a bsc mainnet fork on hardhat if I run the function as a public function to be called after the buy/sell to stabilize the price.

My error comes when I have the stabilize price function called internally after the transfer is done.

My revert string is the least helpful pancake swap message: ‘Pancake: TRANSFER_FAILED’

Checklist of things I have made sure of for this to work:

  • I have given the trading pair enough liquidity of BUSD/Token

  • I have approved the router to transfer busd and the token on behalf of the contract, from the contract

  • The contract has more enough busd and tokens to trade to stabilize the price within range

  • I am getting the correct values when I call getReserves()

Any help or suggestions would be appreciated

Not sure how you call internally after the transfer is done. What contract does that?

I guess that having enough bnb is not the problem.

You can override the standard transfer method like so:

    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal override {
        super._transfer(sender, recipient, amount);
        if (!inSwap) {
            _checkIfBuyBackNeeded();
        }
    }

A lot of tokens override the transfer function so they can add bot protection, add liquidity, etc.

And I gave the contract bnb as well, forgot to mention that. But the trading pair is busd/token so it shouldn’t have to deal with bnb. It’s just swapExactTokensForTokens

I’m thinking that you could try to add some events, remove some logic, to see if it works as expected.
You are testing on mainnet now?

I am using a mainnet fork on hardhat using the bsc archival node url. It allows you to use all the resources of bsc mainnet such as pancake swap’s liquidity in a local dev chain way

Ok, then you can do tests easily.

You can try only with an event in this function to see if it works as expected.

You could also try debugging in remix maybe.

Just tested and it does work. I mean it works perfectly as suspected when I don’t have it called in _transfer . If i make it public and call it right after the trade in my test file, I can log the values and the price remains in-range. So maybe it has to do with tx.origin? Although wouldn’t they both have the same tx.origin anyway

I mean to test directly with that internal function, but with an event instead of more complex logic.

Yes I know, I did test directly and the event is emitted