Read token tax from a token
miohtama opened this issue · 1 comments
Some tokens with ponzinomis have a token tax. This is especially popular on wild west blockchains like BNB Chain and PancakeSwap.
Token tax is used to
- Create deflanatory tokens
- Create malicious honey pots for trading bots ("buy only") - effectively a very high tokex tax like 90% on sell
An example trading pair and token with token tax is ELEPHANT-BUSD.
- Buy has 10% tax
- Sell has 10% tax
honeypot.is is an independent service to check the token tax. It does this by (likely) running Ganache mainnet fork and simulates the transactions. There is no API to ask this information.
Step 1: Read the token tax with Python
To figure out the amount of different token taxes (buy, sell, transfer) one needs to run a simulated transaction in Ganache.
Here is a pseudo-Python code to do it:
from eth_account.signers.local import LocalAccount
from eth_typing import HexAddress
from web3 import Web3
from eth_defi.uniswap_v2.deployment import UniswapV2Deployment
from tradeexecutor.utils import dataclass
@dataclass
class TokenTaxInfo:
"""Different token taxes we figured out."""
#: Token in the question
base_token: HexAddress
#: Which token we traded against it
quote_token: HexAddress
#: How much % we lost of the token on buy
buy_tax: float
#: How much % we lose the token when we transfer between addresses
transfer_tax:float
#: How much % we lose the token when we sold it
sell_tax: float
def estimate_token_taxes(
uniswap: UniswapV2Deployment,
base_token: HexAddress,
quote_token: HexAddress,
buy_account: LocalAccount,
sell_account: LocalAccount
) -> TokenTaxInfo:
"""Estimates different token taxes for a token by running Ganache simulations for it.
:param uniswap:
Uniswap deployment on a Ganache mainnet fork.
Set up prior calling this function.
See `ganache.py` and `test_ganache.py` for more details.
:param base_token:
The token of which tax properties we are figuring out.
:param quote_token:
Address of the quote token used for the trading pair. E.g. `BUDS`, `WBNB`
Based on this information we can derive Uniswap trading pair address.
:param buy_account:
The account that does initial buy to measure the buy tax.
This account must be loaded with gas money (ETH/BNB) and `quote_token`
for a purchase.
:param sell_account:
The account that receives the token transfer and does the sell to measure the sell tax.
This account must be loaded with gas money for the sell.
:return:
ToxTaxInfo tells us what we figure out about taxes.
This can be later recorded to a database.
"""
web3: Web3 = uniswap.web3
# Figure out base_token/quote_token trading pair
# Buy base_token with buy_account
# Measure the loss as "buy tax"
# Transfer tokens to sell_account
# Measure the loss as "transfer tax"
# Sell tokens
# Measure the loss as "sell tax"
The TokenTaxInfo
info can be then stored in a database or similar, like SQL, JSON file repo and so on.
It can be later retrieved when you want to trade tokens.
Step 2: Making taxed tokens easily tradeable with Python
Create a buy/sell_with_tax(token_tax_info: TokenTaxInfo, max_slippage)
function that considers slippage and token tax and correctly handles trading these kinds of tokens.
- Normally buying ELELPHANT-BUSD would revert
- Normally selling a token tax token would fail with
execution reverted: TransferHelper: TRANSFER_FROM_FAILED
because there is a mismatch betweenallowance()
and swap amount
Create four test based on BSC mainnet fork using the existing Ganache fixtures
- Naive buy of ELEPHANT fails
- Taxed buy of ELEPHANT success, we can calculate the taxed amount after the buy (update
analyse_trade
to return this value) - Naive sell of ELEPHANT fails
- Taxed sell of ELEPHANT success, we can calculate the taxed amount after the sell
- Comment how this can be also considered in three-way trade (BUSD-BNB-ELEPHANT)
I added a new manual script:
https://github.com/tradingstrategy-ai/web3-ethereum-defi/blob/master/scripts/fetch-bnb-chain-pairs.py (git master, you might need to do git rebase to your branch)
It fetches all BNB Chain trading pairs. Because the resulting JSON file is 20 MB, I decided not to commit it.
- Can you check if you can regenerate
/tmp/bnb-chain-trading-pairs.json
with this script? - Instructions are at the start of the script
- If you can get the trading pairs downloaded, then the next step would be to create a new script in
scripts/
folder that will try to get tax of all of the tokens (or most of the tokens) in the list.
This will do "data" test. It is likely that we start to see some errors or Ganache failure. But it is a good attempt how far we get to the list.
- The results can be saved in JSON, or similar, but not strictly necessary, as we can have this data to go directly to SQL database and then publish on Trading Strategy API, so we or others do not need to run the token tax fetcher in the future. It's only needed if new tokens are added.