Blog

The most interesting and unique issue for transfer-tax tokens.

As we all know, most transfer-tax tokens implement a mechanism to auto-add liquidity and auto-swap tokens, during the internal _transfer.

Have you realized that these auto methods are not executed when the from address is the pair? For example, during a purchase transaction.
Well, there is a pretty cool explanation for this.

Let's consider the buy flow to understand it:

Buy Transaction in AMM Pairs:

The transaction starts with a user sending a base token (like USDC) to the pair (lets call it TAX/USDC Pair). The .swap function in the pair is then triggered. This function, as part of its logic, optimistically transfers the TaxToken (or any other token involved in the swap) to the recipient.

If the TaxToken contract has an auto-swap or auto-liquidity feature implemented in its _transfer function, and this feature is triggered during the transfer to the recipient, it would attempt to interact with the pair again (to swap TaxToken for another token, like USDC, as part of adding liquidity or swapping for another purpose).

However, since the original .swap call from the pair is still in progress, the pair contract typically employs a lock mechanism for safety reasons. This is a critical security measure to prevent issues like reentrancy attacks.

As a result of this reentrancy protection, if the TaxToken's auto-swap feature attempts to call the pair's swap function again, it will be reverted due to the ongoing execution of the initial swap. This leads to a situation where neither the initial swap nor the auto-swap can complete successfully, causing the whole transaction to fail.

To avoid such issues, it's important to design the token contract in a way that it does not trigger auto-swap or auto-liquidity features when the token is being transferred as part of the pair's .swap execution, respectively just check if the from address is the pair. This is why the _transfer function in the contract likely checks if the from address is a market pair and, if so, avoids executing the auto-swap logic.