# How Crius measures token taxes (realized vs simulated)

> How Crius measures buy, sell and transfer taxes on Robinhood Chain tokens from real trades and from a simulated buy and sell, how the two are combined, and how tax changes are tracked.

Source: https://docs.crius.sh/concepts/taxes/ · Updated 2026-10-28

A token’s tax is the part of a trade that doesn’t reach the trader: the pool sends 1,000 tokens and the buyer receives 930. Crius measures taxes two ways for every Robinhood Chain token. **Realized** taxes come from real trades: what traders actually paid. **Simulated** taxes come from a test buy, transfer and sell run against the latest block. Real trades are the ground truth when there are enough of them; the simulation fills the gap for new tokens and catches tokens that block sells.

## Realized tax: from real trades

For every trade, Crius compares the tokens the pool sent (or received) with what the trader’s wallet received (or sent). The difference is that trade’s tax, whoever takes it: the token contract, a fee-on-transfer mechanism or the pool’s Uniswap v4 hook. Each trade on the [trade tape](https://docs.crius.sh/reference/trades/trade-tape/) carries it as `fees.token_tax.pct`.

From those per-trade taxes, `/security` builds the current rate:

-   **The median of the latest 50 trades per side**, within the last 30 days (`tax.realized.window: "30d"`). A median ignores the odd trade that paid much more or less than the rest.
-   **The developer is measured separately.** `tax.realized.by_wallet_class` has `others_sell_pct` for ordinary sellers and `dev_sell_pct` for the developer, so a developer who sells tax-free doesn’t hide the tax everyone else pays. The headline rate uses ordinary wallets.
-   **`tax.confidence`** is `high` with 20+ measured trades, `medium` with 3+ and `low` below that. `tax.realized.samples` gives the counts.

Example [Anonymous · no key · 1 credit](https://docs.crius.sh/reference/security/security-checks/)

### A median that ignores outliers: CHARGE

Charge AI (0x7b8892cea949bc60d494681d1bc3ea96071ab0b8) shows a 0% sell tax, but one sell paid far more. Which is right?

GET/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/security

  

**cURL**

```bash
curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/security"
```

**JavaScript**

```js
const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/security");
const { data, meta } = await res.json();
```

**Python**

```python
import requests

r = requests.get(
    "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/security",
)
body = r.json()
print(body["data"])
```

**Real response 200 Captured Oct 28, 2026 · 177 lines (arrays trimmed)**

```json
{
  "data": {
    "contract": {
      "blacklist": false,
      "can_change_limits": false,
      "can_change_tax": false,
      "cooldown": false,
      "implementation": null,
      "is_proxy": false,
      "mintable": false,
      "owner": null,
      "ownership": "none",
      "pausable": false,
      "proxy_kind": null,
      "self_destruct": false,
      "trading_switch": false,
      "upgradeable": false,
      "verified": null
    },
    "flags": [
      "unverified"
    ],
    "honeypot": {
      "is_honeypot": false,
      "reason": null,
      "selective": false
    },
    "hook": {
      "address": "0xe5e702641ea86f4ae6cc3cdaed2b886f976be044",
      "capabilities": {
        "can_block_swaps": false,
        "can_gate_liquidity": false,
        "can_modify_liquidity_amounts": false,
        "can_modify_swap_amounts": true
      },
      "code": {
        "admin_functions": [],
        "checked_ts": 1793207140434,
        "code_hash": "0xc21b1e6c1b45403e81a581f22ed6d9c747997af1cfdac1b1dc9f4b1d346a10db",
        "family": "0xabda3266e50c",
        "kind": "contract",
        "logic": null,
        "owner": "0x263ed295dafae1d9aadd6e56c4b6f9f38ee019dd",
        "ownership": "active",
        "size": 15167
      },
      "family": {
        "honeypot_pct": 0,
        "hooks": 22,
        "id": "0xabda3266e50c",
        "liquidity_pulled_pct": 0.684086,
        "pools_traded": 10525,
        "taxed_pct": 51.9715,
        "verified_hooks": 1
      },
      "flags": [],
      "name": "PonsV2MemeHook",
      "observed": {
        "dynamic_tax_pools": 13,
        "first_trade_ts": 1785866942000,
        "honeypot_pools": 0,
        "last_trade_ts": 1793223683000,
        "liquidity_pulled_pct": 0.66813,
        "liquidity_pulled_pools": 70,
        "max_buy_tax_pct": 10.99,
        "max_sell_tax_pct": 0.7,
        "median_pool_life_min": 53423.5,
        "pools": 10478,
        "pools_traded": 10477,
        "tax_measured_pools": 10392,
        "taxed_10pct_pools": 35,
        "taxed_pools": 5463,
        "volume_usd": 5384607135
      },
      "pattern": {
        "description": "hooks that change swap amounts only",
        "honeypot_pct": 0.0696347,
        "id": "swap_delta_only",
        "liquidity_pulled_pct": 7.93603,
        "pools_traded": 43082,
        "taxed_pct": 15.7537
      },
      "permissions": [
        "beforeInitialize",
        "afterSwap",
        "afterSwapReturnDelta"
      ],
      "risk": [
        "can_modify_swap_amounts"
      ],
      "risk_level": "low"
    },
    "known_asset": false,
    "launch": {
      "flags": [],
      "lp_top_wallet": {
        "address": "0x2d424d69b1ead72b30de4c7fe4c53e4853e1419d",
        "liquidity_usd": 3.0953,
        "pct": 0.0551662
      },
      "sniper_supply_pct": 6.09195,
      "sniper_top_wallet_pct": 6.09195,
      "sniper_wallets": 1,
      "sniper_window_blocks": 10,
      "uniform_holders": null,
      "wallet_farm": null
    },
    "limits": {},
    "liquidity": {
      "status": "partially_locked",
      "summary": {
        "burned_pct": 0,
        "locked_pct": 99.8878,
        "next_unlock_ts": null,
        "protocol_fee_pct": 0,
        "unlocked_in_wallets_pct": 0.1122,
        "weighting": "by pool liquidity_usd"
      }
    },
    "primary_dex": "uniswap_v4",
    "risk": "low",
    "score": 95,
    "tax": {
      "buy_pct": 2.99,
      "confidence": "high",
      "realized": {
        "buy_pct": 2.99,
        "by_wallet_class": {
          "dev_sell_pct": null,
          "others_sell_pct": 0
        },
        "last_sample_ts": 1793196204000,
        "max_sell_pct_seen": 96.64,
        "samples": {
          "buys": 2539,
          "sells": 1873
        },
        "sell_pct": 0,
        "window": "30d"
      },
      "sell_pct": 0,
      "simulated": null,
      "source": "realized",
      "transfer_pct": null
    },
    "tax_history": [
      {
        "from_block": 88385895,
        "pct": 0,
        "side": "buy"
      },
      {
        "from_block": 88387118,
        "pct": 0,
        "side": "sell"
      },
      {
        "from_block": 88461329,
        "pct": 3,
        "side": "buy"
      }
    ],
    "tax_history_total": 29,
    "tax_mode": "dynamic",
    "token": "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8"
  },
  "meta": {
    "block": 100406827,
    "block_age_ms": 1163,
    "block_ts": 1793225080000,
    "chain": "robinhood",
    "finalized_block": 100397649,
    "lag_ms": 64,
    "safe_block": 100401329,
    "simulation": "no V2 WETH pair: realized tax only"
  }
}
```

What this tells you

-   `tax.sell_pct: 0` while `tax.realized.max_sell_pct_seen: 96.64`. Ordinary sells pay nothing; one sell lost almost everything. The median of recent sells is the rate a new seller can expect.
-   `tax.buy_pct: 2.99`, from 2,539 buys and 1,873 sells measured (`confidence: "high"`).
-   `tax_history_total: 29` and `tax_mode: "dynamic"`: the measured rate has changed many times. The first entries show 0% on both sides at launch, then 3% on buys from block 88461329, eight blocks after its v4 liquidity was locked in the Pons launch locker at block 88461321 (see the [liquidity example](https://docs.crius.sh/guides/check-liquidity-locked/)): the launchpad’s fee on the graduated pool.
-   `tax.simulated: null`, `meta.simulation: "no V2 WETH pair: realized tax only"`: with no Uniswap v2 pair to simulate through, real trades are the whole answer.

[Security checks reference](https://docs.crius.sh/reference/security/security-checks/) Runs from your browser on the anonymous plan [Data looks wrong? Report it](mailto:support@crius.sh?subject=Wrong%20data%20in%20docs%20example%3A%20A%20median%20that%20ignores%20outliers%3A%20CHARGE&body=Page%3A%20https%3A%2F%2Fdocs.crius.sh%2Fconcepts%2Ftaxes%2F%23median%0ARequest%3A%20GET%20%2Fv1%2Frobinhood%2Ftoken%2F0x7b8892cea949bc60d494681d1bc3ea96071ab0b8%2Fsecurity%0A%0AWhat's%20wrong%20or%20missing%3F%0A%0A)

## Simulated tax: a test trade at the latest block

When a token has a Uniswap v2 pair with WETH, Crius simulates a full round trip through the Uniswap v2 router at the latest block, without sending anything on chain:

1.  **Buy** about `amount_usd` worth (default $100) and compare the tokens received with what the router quoted: the buy tax.
2.  **Transfer** 10% of the tokens to a second wallet: the transfer tax (`tax.transfer_pct`), and whether transfers work at all (`can_transfer`).
3.  **Approve and sell** half of the rest. The sell tax is the share of tokens that never reached the pair, which doesn’t depend on price impact.

The result is in `tax.simulated`: `can_buy`, `can_sell`, `buy_pct`, `sell_pct`, `transfer_pct`, gas used, and `revert_reason` when a step fails. A buy that works followed by a sell that fails is a honeypot (see [How to detect a honeypot](https://docs.crius.sh/guides/detect-honeypot/)). Results are cached briefly; `fresh=1` runs a new simulation (Starter plan, 20 credits).

## How the two are combined

| Real trades available | `tax.buy_pct` / `tax.sell_pct` | `tax.source` |
| --- | --- | --- |
| Recent buys and sells | Both realized | `realized` |
| Recent buys but no recent sells by ordinary wallets | Buy realized, sell simulated | `realized+simulated` (or `realized` without a simulation) |
| No recent buys | Simulated where available | `simulated`, or `none` without a v2 WETH pair |

When both a realized and a simulated sell tax exist and they differ by more than 2 percentage points, the token gets the `tax_mismatch` flag (−10 points). In the [security score](https://docs.crius.sh/guides/token-security-score/), a buy or sell tax above 5% costs 15 points (`tax_over_5pct`) and above 10% costs 30 (`high_tax`).

## Tax history and dynamic taxes

`tax_history` turns the per-trade taxes of ordinary wallets into segments: a new entry (`from_block`, `side`, `pct` in whole percent) starts when a side’s rate changes and stays changed for at least two trades in a row, so one odd trade doesn’t create a change. `tax_mode` is `dynamic` when either side has more than one segment, else `static`. The response holds the newest 100 segments; `tax_history_total` counts all of them.

A dynamic tax isn’t always a trap. Launchpad tokens often go from 0% on the bonding curve to the launchpad’s fee after graduation, as CHARGE did. What matters is whether someone can still change it: `contract.can_change_tax` with an active owner, or a hook with a fee setter (`fee_changeable` in `hook.flags`).

## Known assets

WETH, USDG and tokenized stocks (`known_asset: true`) have no tax to measure and no WETH pair to simulate against: their tax fields are empty and their trade noise isn’t treated as a tax history.

## Frequently asked questions

**Why does Crius use real trades instead of reading the tax from the contract?**

Because the contract is often not where the tax is. On Robinhood Chain many taxes are taken by a Uniswap v4 hook, some contracts tax only certain wallets or sizes, and a tax variable can say one thing while the transfer logic does another. Comparing what the pool sent with what the wallet received catches all of these.

**Why is the sell tax 0 when one sell paid 96%?**

The headline rate is the median of the latest 50 sells by ordinary wallets, so one odd trade doesn't set it. `tax.realized.max_sell_pct_seen` keeps the worst single sell so you can still see it.

**What does tax\_mismatch mean?**

The simulated sell tax and the realized sell tax differ by more than 2 percentage points. The token may tax differently by wallet or size, or the tax changed recently. It costs 10 points in the security score.

## Related

[Guide **Check token taxes** Get the real buy and sell tax of any Robinhood Chain token in one call, measured from recent trades and checked by simulation. Real examples with a 5% sell tax and a 7% buy tax. Read](https://docs.crius.sh/guides/check-token-taxes/) [Guide **Detect a honeypot** Check whether a Robinhood Chain token can be sold before you buy it. One API call simulates a buy and a sell and checks real trades; a real honeypot example shows the evidence. Read](https://docs.crius.sh/guides/detect-honeypot/) [Guide **Token security score** Score any Robinhood Chain token from 0 to 100 with one API call. Honeypot, buy and sell taxes, owner powers, LP locks, v4 hook risk and insider launches, with real examples. Read](https://docs.crius.sh/guides/token-security-score/) [Concept **v4 hook risk** How Crius rates every Uniswap v4 hook on Robinhood Chain, from its permissions, its code and owner, what happened in its pools and its code family's record, with each risk flag and its threshold. Read](https://docs.crius.sh/concepts/uniswap-v4-hooks/) [API reference **Security checks API** Contract checks (ownership, mint, pause, blacklist, proxy, limits), realized and simulated buy/sell tax, honeypot verdict and, for v4 tokens, the pool hook's permissions and risk. Read](https://docs.crius.sh/reference/security/security-checks/)
