首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检查ERC-20令牌是否是欺诈/蜜罐

检查ERC-20令牌是否是欺诈/蜜罐
EN

Stack Overflow用户
提问于 2022-03-10 00:19:18
回答 2查看 1.2K关注 0票数 3

我正在寻找一种方法来获得一个令牌的买卖税,并检查它是否可以出售一次购买。

要做到这一点,我想到的方法如下:

1-模拟DEX路由器合同上的购买事务

2-模拟DEX路由器合同上的卖出交易

3-如果上述2笔交易是成功的,我可以知道销售税和购买税+是否可以出售。

由于我使用的是调用而不是真实的事务来模拟令牌的买卖,所以我需要进行多个调用来模拟块链状态的改变。

我正在使用ethereum多功能图书馆来完成这个任务。

这是我的密码:

代码语言:javascript
复制
const multicall = new Multicall({ethersProvider: _EVM.provider, tryAggregate: true});
let amoutIn = ethers.utils.parseUnits('300',18);
  let timestamp = Date.now() + 1000 * 60 * 10;
  const contractCallContext =[
{
  reference: 'Router',
  contractAddress: _EVM.DEX.router,
  abi: JSON.parse(Router_ABI),
  calls:[{reference:'foo', methodName:'swapExactTokensForTokens', methodParameters:[amoutIn,0,[ASDC, MIM],"0xa37Aa5C9A682490C64bDC32e60E627A50B66a485",timestamp]}]
}];

let result = await multicall.call(contractCallContext);

问题是我经常从Multicall智能合同中得到不完全的返回值.

还有别的方法可以达到我想要的目标吗?或者我的代码有问题吗?

提前感谢

EN

回答 2

Stack Overflow用户

发布于 2022-06-12 20:08:05

你可以找到这里有一个用于检查任何转帐费用的Python代码示例

代码语言:javascript
复制
def estimate_token_taxes(
        uniswap: UniswapV2Deployment,
        base_token: HexAddress,
        quote_token: HexAddress,
        buy_account: HexAddress,
        sell_account: HexAddress,
        buy_amount: float,
        approve=True,
        quote_token_details: Optional[TokenDetails] = None,
        base_token_details: Optional[TokenDetails] = None,
        gas_limit: Optional[int] = None,
        gas_price: Optional[int] = None,
) -> 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.
    :param approve:
        Perform quote token approval before wap test
   :param base_token_details:
        Pass base token details. If not given automatically fetch.
    :param quote_token_details:
        Pass quote token details. If not given automatically fetch.
    :param gas_limit:
        Use this gas limit for all transactions, so that
        we do not need to call eth_estimateGas on the node.
    :param gas_price:
        Use this gas price for all transactions, so that
        we do not need to call eth_estimateGas on the node.
    :return:
        ToxTaxInfo tells us what we figure out about taxes.
        This can be later recorded to a database.
    """
    web3: Web3 = uniswap.web3
    router = uniswap.router

    if not quote_token_details:
        # No need to consider brokeness of token metadata
        # when calculating tax
        quote_token_details = fetch_erc20_details(web3, quote_token, raise_on_error=False)
    quote_token = quote_token_details.contract

    if not base_token_details:
        # No need to consider brokeness of token metadata
        # when calculating tax
        base_token_details = fetch_erc20_details(web3, base_token, raise_on_error=False)
    base_token = base_token_details.contract

    if gas_limit:
        # Try to eliminate some RPC calls by not doing gas oracle requests
        # https://web3js.readthedocs.io/en/v1.2.11/web3-eth.html#sendtransaction
        generic_tx_params = {
            "gas": gas_limit,
            "gasPrice": gas_price,
        }
    else:
        generic_tx_params = {}

    # approve router to spend tokens
    if approve:
        quote_token.functions.approve(router.address, quote_token_details.convert_to_raw(buy_amount)).transact(
            {"from": buy_account} | generic_tx_params)

    path = [quote_token.address, base_token.address]
    amountIn = quote_token_details.convert_to_raw(buy_amount)
    # Figure out base_token/quote_token trading pair
    initial_base_bal = base_token.functions.balanceOf(buy_account).call()

    # Buy base_token with buy_account
    try:
        logger.info("Attempting to buy for path %s", path)
        router.functions.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            amountIn,
            0,
            path,
            buy_account,
            FOREVER_DEADLINE
        ).transact({"from": buy_account} | generic_tx_params)
    except ContractLogicError as e:
        msg = str(e)
        if "TRANSFER_FAILED" in msg:
            raise TransferFromError(f"Token does not co-operate:{base_token_details.symbol} - {quote_token_details.symbol}, {e} to router {router.address}") from e
        raise
    except Exception as e:
        raise SwapError(f"swapExactTokensForTokensSupportingFeeOnTransferTokens() buy failed:{base_token_details.symbol} - {quote_token_details.symbol}, {e} to router {router.address}") from e

    received_amt = base_token.functions.balanceOf(buy_account).call() - initial_base_bal

    if received_amt == 0:
        # Nothing was received when we bought the token, so assume 100% tax
        # Would cause division by zero later
        return TokenTaxInfo(base_token.address, quote_token.address, 1.0, 1.0, 1.0)

    uniswap_price = router.functions.getAmountsOut(amountIn, path).call()[1]

    # Measure the loss as "buy tax"
    buy_tax_percent = (uniswap_price - received_amt) / uniswap_price

    # Transfer tokens to sell_account
    # Measure the loss as "transfer tax"
    try:
        base_token.functions.transfer(sell_account, received_amt).transact({"from": buy_account} | generic_tx_params)
    except ValueError as e:
        if "out of gas" in str(e):
            raise OutOfGasDuringTransfer(f"Out of gas during transfer: {e}") from e
        else:
            raise TransferFailure(f"Transfer failure: {e}") from e

    received_amt_by_seller = base_token.functions.balanceOf(sell_account).call()

    transfer_tax_percent = (received_amt - received_amt_by_seller) / received_amt

    # Sell tokens
    try:
        base_token.functions.approve(router.address, received_amt_by_seller).transact({"from": sell_account} | generic_tx_params)
    except ValueError as e:
        if "out of gas" in str(e):
            raise ApprovalFailure() from e

    path = [base_token.address, quote_token.address]

    sell_tax = 0
    sell_tax_percent = 0
    try:
        # this method will revert in case of low liquidity of the token
        logger.info("Attempting to see for path %s", path)
        router.functions.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            received_amt_by_seller,
            0,
            path,
            sell_account,
            FOREVER_DEADLINE
        ).transact({"from": sell_account} | generic_tx_params)
    except ValueError as e:
        if "VM Exception while processing transaction: revert" in str(e):
            raise SellFailed(f"Could not sell {base_token_details.symbol} - {quote_token_details.symbol}: {e}") from e
        elif "out of gas" in str(e):
            raise OutOfGasDuringTransfer() from e
        raise
    except Exception as e:
        raise SwapError(f"Sell failed. swapExactTokensForTokensSupportingFeeOnTransferTokens() method failed: {base_token_details.symbol} - {quote_token_details.symbol}: {e}") from e

    # Measure the loss as "sell tax"
    received_amt_after_sell = quote_token.functions.balanceOf(sell_account).call()
    uniswap_price = router.functions.getAmountsOut(received_amt_by_seller, path).call()[1]

    if received_amt_after_sell > 0:
        sell_tax = uniswap_price - received_amt_after_sell
        sell_tax_percent = (sell_tax / uniswap_price) if uniswap_price > 0 else 0

    return TokenTaxInfo(base_token.address, quote_token.address, buy_tax_percent, transfer_tax_percent,
                        sell_tax_percent)

您还可以在这里找到现有令牌税收数据的API和数据集转储。

票数 2
EN

Stack Overflow用户

发布于 2022-03-27 02:43:44

我也对答案感兴趣。也许您可以查看honeypot.is,并在那里看到任何帮助(我没有附属于他们)。我对写机器人有点陌生,只是碰巧撞上了他们的网站。告诉我你发现了什么!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71417463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档