How to check a Robinhood Chain token's buy and sell tax
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.
Call GET /v1/robinhood/token/{address}/security and read tax.buy_pct and tax.sell_pct. They are measured from what real buyers and sellers paid (tax.source: "realized"), backed by a buy-and-sell simulation where the token has a Uniswap v2 WETH pair. A tax over 5% adds the tax_over_5pct flag, over 10% high_tax. No API key needed.
A token tax is the share of each trade the token (or its pool) keeps for itself: with Recast’s 7% buy tax, $100 of ETH buys about $93 of tokens, and with Ruby’s 5% sell tax you get about 5% less than the pool paid out. Crius measures it from real trades on Robinhood Chain, so the number you get is what buyers and sellers actually paid in the last 30 days, not what a contract claims. One call to /security returns the buy tax, the sell tax, how sure the number is and every past change.
Get the buy and sell tax in one call
A 5% sell tax: Ruby (RUBY)
Ruby (0x8b5a7a19fbd3d8e8422643fc229b3ab08697c0be) has a renounced contract. What does it really cost to sell?
curl "https://api.crius.sh/v1/robinhood/token/0x8b5a7a19fbd3d8e8422643fc229b3ab08697c0be/security"const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x8b5a7a19fbd3d8e8422643fc229b3ab08697c0be/security");const { data, meta } = await res.json();import requests
r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x8b5a7a19fbd3d8e8422643fc229b3ab08697c0be/security",)body = r.json()print(body["data"])Real response 200 Captured Oct 28, 2026 · 191 lines (arrays trimmed)
{ "data": { "contract": { "blacklist": false, "can_change_limits": false, "can_change_tax": false, "cooldown": false, "implementation": null, "is_proxy": false, "mintable": false, "owner": "0x000000000000000000000000000000000000dead", "ownership": "renounced", "pausable": false, "proxy_kind": null, "self_destruct": false, "trading_switch": false, "upgradeable": false, "verified": "none" }, "flags": [ "tax_over_5pct", "hook_can_block_swaps", "hook_medium_risk", "unverified" ], "honeypot": { "is_honeypot": false, "reason": null, "selective": false }, "hook": { "address": "0x97240e95756c7b70db1ffaeee85a6c091c33a4ce", "capabilities": { "can_block_swaps": true, "can_gate_liquidity": false, "can_modify_liquidity_amounts": true, "can_modify_swap_amounts": true }, "code": { "admin_functions": [], "checked_ts": 1793207142599, "code_hash": "0x5cb5a35842eb82ff5c9dbed2dca84d023823d841a2c0fc642568bc8ff276f72f", "family": "0xaa8854cbf2bd", "kind": "contract", "logic": null, "owner": "0x33acedd086ee7fec19764b5f4a93a6ef067953f5", "ownership": "active", "size": 24040 }, "family": { "honeypot_pct": 0, "hooks": 3, "id": "0xaa8854cbf2bd", "liquidity_pulled_pct": 0, "pools_traded": 10, "taxed_pct": 90, "verified_hooks": 0 }, "flags": [ { "evidence": "7 of its 7 measured pools take 1%+ per trade (median per pool, up to 6.3%); only 10.83% of traded hooked pools tax at all", "flag": "tax_observed", "severity": "medium" }, { "evidence": "can take part of every swap (return delta); 4.55% of traded pools of hooks that can block swaps and change swap amounts taxed, 0.61% became honeypots", "flag": "can_modify_swap_amounts", "severity": "low" } ], "name": null, "observed": { "dynamic_tax_pools": 0, "first_trade_ts": 1793119940000, "honeypot_pools": 0, "last_trade_ts": 1793223286000, "liquidity_pulled_pct": 0, "liquidity_pulled_pools": 0, "max_buy_tax_pct": 2.545, "max_sell_tax_pct": 6.28, "median_pool_life_min": 1380, "pools": 18, "pools_traded": 8, "tax_measured_pools": 7, "taxed_10pct_pools": 0, "taxed_pools": 7, "volume_usd": 924751 }, "pattern": { "description": "hooks that can block swaps and change swap amounts", "honeypot_pct": 0.608377, "id": "before_swap_with_delta", "liquidity_pulled_pct": 21.5893, "pools_traded": 18574, "taxed_pct": 4.55475 }, "permissions": [ "beforeInitialize", "afterAddLiquidity", "beforeSwap", "afterSwap", "beforeSwapReturnDelta" ], "risk": [ "can_block_or_reprice_swaps", "can_modify_swap_amounts", "can_modify_liquidity_amounts", "unverified" ], "risk_level": "medium" }, "known_asset": false, "launch": { "flags": [], "lp_top_wallet": { "address": "0x20ac92362ead44f457913ca1a6c24fae049078d9", "liquidity_usd": 23.0571, "pct": 0.214633 }, "sniper_supply_pct": 1.77655, "sniper_top_wallet_pct": 1.77655, "sniper_wallets": 1, "sniper_window_blocks": 10, "uniform_holders": null, "wallet_farm": null }, "limits": {}, "liquidity": { "status": "partially_locked", "summary": { "burned_pct": 99.2777, "locked_pct": 0, "next_unlock_ts": null, "protocol_fee_pct": 0, "unlocked_in_wallets_pct": 0.722259, "weighting": "by pool liquidity_usd" } }, "primary_dex": "uniswap_v4", "risk": "medium", "score": 70, "tax": { "buy_pct": 0.84, "confidence": "high", "realized": { "buy_pct": 0.84, "by_wallet_class": { "dev_sell_pct": null, "others_sell_pct": 5.28 }, "last_sample_ts": 1793221716000, "max_sell_pct_seen": 16.65, "samples": { "buys": 8, "sells": 240 }, "sell_pct": 5.28, "window": "30d" }, "sell_pct": 5.28, "simulated": null, "source": "realized", "transfer_pct": null }, "tax_history": [ { "from_block": 99421932, "pct": 5, "side": "sell" }, { "from_block": 99791485, "pct": 1, "side": "buy" } ], "tax_history_total": 2, "tax_mode": "static", "token": "0x8b5a7a19fbd3d8e8422643fc229b3ab08697c0be" }, "meta": { "block": 100406622, "block_age_ms": 595, "block_ts": 1793225060000, "chain": "robinhood", "finalized_block": 100397649, "lag_ms": 100, "safe_block": 100401329, "simulation": "no V2 WETH pair: realized tax only" }}What this tells you
tax.sell_pct: 5.28andtax.buy_pct: 0.84, from real trades (tax.source: "realized",confidence: "high").tax.realized.samplescounts 240 sells and 8 buys measured.tax.realized.by_wallet_class.others_sell_pct: 5.28is what ordinary sellers pay;dev_sell_pct: nullmeans the developer hasn’t sold, so there is nothing to compare.tax.realized.max_sell_pct_seen: 16.65is the worst single sell. The headline rate is a median of recent trades, so one unlucky trade doesn’t set it.tax_historyshows a 5% sell tax from block 99421932 and a 1% buy tax from block 99791485;tax_mode: "static"means neither side has changed since.- The token contract can’t tax:
contract.can_change_tax: false,ownership: "renounced". The tax comes from the pool’s v4 hook, whosehook.flagsincludetax_observed(“7 of its 7 measured pools take 1%+ per trade… up to 6.3%”). - The 5.28% costs 15 points (
tax_over_5pct), and the hook costs 10 more (hook_medium_risk):score: 70,risk: "medium".
A 7% buy tax that changed over time: Recast (CAST)
Recast (0xb656eadd009b3b409d7a0971e50df2f0e4ddef5a) is a graduated Pons token. How much do buyers lose?
curl "https://api.crius.sh/v1/robinhood/token/0xb656eadd009b3b409d7a0971e50df2f0e4ddef5a/security"const res = await fetch("https://api.crius.sh/v1/robinhood/token/0xb656eadd009b3b409d7a0971e50df2f0e4ddef5a/security");const { data, meta } = await res.json();import requests
r = requests.get( "https://api.crius.sh/v1/robinhood/token/0xb656eadd009b3b409d7a0971e50df2f0e4ddef5a/security",)body = r.json()print(body["data"])Real response 200 Captured Oct 28, 2026 · 188 lines (arrays trimmed)
{ "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": [ "tax_over_5pct", "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": "0x441568fdd10b00ddc90b4a95aee03d8d06242283", "liquidity_usd": 2.08528, "pct": 0.0195019 }, "sniper_supply_pct": 0.61622, "sniper_top_wallet_pct": 0.61622, "sniper_wallets": 1, "sniper_window_blocks": 10, "uniform_holders": null, "wallet_farm": null }, "limits": {}, "liquidity": { "status": "locked", "summary": { "burned_pct": 0, "locked_pct": 99.9805, "next_unlock_ts": null, "protocol_fee_pct": 0, "unlocked_in_wallets_pct": 0.019502, "weighting": "by pool liquidity_usd" } }, "primary_dex": "uniswap_v4", "risk": "low", "score": 80, "tax": { "buy_pct": 6.99, "confidence": "high", "realized": { "buy_pct": 6.99, "by_wallet_class": { "dev_sell_pct": null, "others_sell_pct": 0 }, "last_sample_ts": 1793223683000, "max_sell_pct_seen": 1, "samples": { "buys": 1107, "sells": 530 }, "sell_pct": 0, "window": "30d" }, "sell_pct": 0, "simulated": null, "source": "realized", "transfer_pct": null }, "tax_history": [ { "from_block": 82850924, "pct": 0, "side": "buy" }, { "from_block": 82929088, "pct": 0, "side": "sell" }, { "from_block": 85677230, "pct": 1, "side": "buy" }, { "from_block": 85686101, "pct": 0, "side": "buy" }, { "from_block": 90626923, "pct": 7, "side": "buy" } ], "tax_history_total": 9, "tax_mode": "dynamic", "token": "0xb656eadd009b3b409d7a0971e50df2f0e4ddef5a" }, "meta": { "block": 100406621, "block_age_ms": 400, "block_ts": 1793225060000, "chain": "robinhood", "finalized_block": 100397649, "lag_ms": 10, "safe_block": 100401329, "simulation": "no V2 WETH pair: realized tax only" }}What this tells you
tax.buy_pct: 6.99andtax.sell_pct: 0, measured over 1,107 buys and 530 sells (confidence: "high").tax_mode: "dynamic": the buy tax has moved.tax_history_total: 9changes; the first ones show the buy side going from 0 to 1%, back to 0, then 7% from block 90626923.tax.simulated: nullandmeta.simulation: "no V2 WETH pair: realized tax only": the token only trades in a Uniswap v4 pool, so there is no router simulation and the realized rate is the answer.flags: ["tax_over_5pct", "unverified"]andscore: 80, stillrisk: "low". The score treats a 7% buy tax as a cost, not a trap: you can buy and sell, you just pay for it.
What the tax fields mean
| Field | Meaning |
|---|---|
tax.buy_pct, tax.sell_pct | The current tax in percent, from real trades where there are any, else from the simulation. null when there is nothing to measure. |
tax.source | realized (real trades), realized+simulated (buys from trades, sells from the simulation), simulated, or none. |
tax.confidence | high with 20+ measured trades, medium with 3+, low below that. |
tax.realized.samples | How many buys and sells were measured. |
tax.realized.by_wallet_class | others_sell_pct for ordinary sellers and dev_sell_pct for the developer, measured separately. |
tax.realized.max_sell_pct_seen | The highest tax a single sell paid. Much higher than sell_pct means some sells were hit hard. |
tax.simulated | The simulated buy → transfer → sell at the latest block (can_buy, can_sell, buy_pct, sell_pct, transfer_pct, revert_reason), or null without a Uniswap v2 WETH pair. |
tax.transfer_pct | Tax on a plain wallet-to-wallet transfer, from the simulation. |
tax_mode | static, or dynamic when a side's measured rate has changed more than once. |
tax_history | Each change: from_block, side (buy or sell) and pct in whole percent. tax_history_total counts them all. |
contract.can_change_tax | The contract has a function to change its tax. It only matters while contract.ownership is active. |
How the realized and simulated numbers are produced, and when they disagree, is explained in How Crius measures taxes.
Use it in your app
-
Call
/securityfor the token. It’s on the anonymous plan; with a key it costs 1 credit. The tax fields come back with the rest of the security check. -
Show both sides and the evidence. Display
buy_pctandsell_pctwithconfidence, and say when they come from fewer than 20 trades. -
Warn on taxes that can move. Treat
tax_mode: "dynamic",contract.can_change_taxwith an active owner, or a hook flaggedfee_changeableordynamic_taxas “the tax may change after you buy”. -
Use the tax in your quote. Take
buy_pctoff the tokens a user expects to receive andsell_pctoff the ETH they expect back, so the slippage setting covers the tax.
// Read a token's tax before quoting a trade.const token = "0x8b5a7a19fbd3d8e8422643fc229b3ab08697c0be"; // Rubyconst res = await fetch(`https://api.crius.sh/v1/robinhood/token/${token}/security`);const { data } = await res.json();const { buy_pct, sell_pct, source, confidence } = data.tax;
console.log(`buy ${buy_pct ?? "?"}%, sell ${sell_pct ?? "?"}% (${source}, ${confidence} confidence)`);if (data.tax_mode === "dynamic") console.warn(`tax has changed ${data.tax_history_total} times`);if (data.flags.includes("high_tax")) console.warn("tax above 10%");Frequently asked questions
How to check token tax on Robinhood Chain?
Send GET https://api.crius.sh/v1/robinhood/token/{address}/security (no key needed) and read tax.buy_pct and tax.sell_pct, in percent. Check tax.source and tax.confidence to see what the numbers are based on, and tax_mode to see whether the tax has changed over time.
Does Crius read the tax from the contract or measure it?
It measures it. For every trade Crius compares what the pool sent with what the wallet received, so the tax is what traders really paid, whether the token contract or a Uniswap v4 hook takes it. Where the token has a Uniswap v2 WETH pair, a simulated buy, transfer and sell at the latest block backs it up (tax.simulated). The contract is only checked for whether someone can still change the tax (contract.can_change_tax).
The token contract has no tax and ownership is renounced. Why does the API show a 5% sell tax?
Because the tax is taken somewhere else, usually in the pool's Uniswap v4 hook. Ruby (0x8b5a7a19fbd3d8e8422643fc229b3ab08697c0be) has a renounced contract with can_change_tax: false, yet sellers pay 5.28%: its pool's hook takes it. That is why Crius measures taxes from trades instead of reading the token's code.
Can a token's tax change after I buy?
Yes, if someone can still change it. tax_mode: "dynamic" means the measured rate has already changed more than once; tax_history lists each change with the block it took effect. contract.can_change_tax with an active owner, or a hook with a fee setter, means it can change again. Subscribe to the WebSocket stream or re-check before each trade.
Is the ~3% buy fee on Pons tokens a tax?
It is counted in tax.buy_pct, because buyers receive less than the pool sent. On graduated Pons tokens it is the launchpad's standard fee taken by its v4 hook (sockets pays 2.69%), and it stays under the 5% that costs points in the security score.
Related
Get your free Crius API key
Every example on this page works with a free key: higher rate limits than the anonymous plan, holders, wallets and the WebSocket stream. No card needed.
- Robinhood Chain (4663) only, from our own archive nodes
- REST + WebSocket
- Pay on-chain or by card