Tokens and risks
Any token with a route can be traded. Orblivion doesn't decide what you may trade: it screens each token, tells you what it found, and asks for your explicit acceptance before a trade with a severe finding.
Any token with a route#
- The core assets go by symbol:
ETH,WETH,USDG,cbBTC,ORBIO, and the stock tokensNVDAandSPY. Their addresses are pinned in the SDKs and published inGET /api/v1/config. - Every other token goes by its contract address, in every request and answer. A symbol means nothing on chain: there are many fake USDGs, and popular Orbio agent tokens have dozens of copies. A request that names any other token by symbol is refused (
TOKEN_NOT_ALLOWED). - A token is tradable when Orblivion can build a trade through at least one venue: a Uniswap v2, v3 or v4 pool (through WETH, USDG or ORBIO), or its Pons bonding curve while it is still on one. The only refusal about a token itself is
NO_ROUTE. - A token Orblivion hasn't seen is screened on demand when you first name it (within about 8 seconds). Screening is rate-limited per caller and overall:
429 RATE_LIMITEDor503 SCREEN_UNAVAILABLE, each withRetry-After.
GET /api/v1/tokens/<address> returns a token's record: its tier, kind, venues, liquidity, price reference, flags, taxes and disclosures, plus plain-language warnings.
Tiers#
Every token gets a tier. A tier is a risk class and the defaults a token trades with, never a permission:
| Tier | Which tokens | Price reference | Deviation allowed from it |
|---|---|---|---|
| A | a Chainlink feed and $1M or more of liquidity | Chainlink, or the reference pool's time-weighted average while the feed is stale | the asset's own cap (60 bps by default) |
| B | $100k to $1M, or a usable independent reference without a feed | Chainlink, a 30-minute pool average, or a median of distinct pools | 150 bps |
| C | anything else with a route, Orbio agent tokens included | the venue's own price, or none | 300 bps, plus the curve's or hook's fee and the creator's tax |
A record's limits also carries a size hint: where price impact may start. A trade above it is not refused; its impact is disclosed.
Disclosures#
Every token record, quote, plan, simulation and session trade answers, at its top level (here, a plan that buys a long-tail token with ETH):
"risks": [
{"code": "TRANSFER_TAX", "severity": "severe", "detail": "..."},
{"code": "LOW_LIQUIDITY", "severity": "info", "detail": "..."}
],
"fee_bps": 50,
"fee_class": "other",
"fee_tier": 50,
"shield": false,
"shield_available": truerisks is always present (an empty list when there are none), severe first. It holds the tokens' own findings and the trade's own: its price impact, an unknown hook on the route, a stale price reference.
fee_bps is Orblivion's fee for the trade. A quote, plan, simulation or session trade also says its fee_class (major when both tokens are majors, else other) and fee_tier. A trade with any token outside the majors (ETH, WETH, USDG, cbBTC, ORBIO and Robinhood stock tokens) is other, so it pays 0.50%. See Fees and gas.
The full table#
| Code | Severity | Disclosed on | Meaning |
|---|---|---|---|
HONEYPOT | severe | every request | the sell leg of Orblivion's buy-then-sell simulation failed: you may not be able to sell |
TRANSFER_TAX | severe | every request | a plain transfer delivers less than was sent |
LOOKALIKE | severe | every request | imitates a core asset's name or symbol at another address |
AMOUNT_HOOK | severe | every request | a v4 hook on the route can change swap amounts (the minimum output still holds) |
HIGH_PRICE_IMPACT | severe | every request | the trade moves the price more than 10% |
UNSCREENED | severe | every request | Orblivion's screen couldn't finish for this token, so a honeypot or tax can't be ruled out |
IMPERSONATOR | severe | Shield only | Dossier found the project behind this name presents another contract |
PRICE_IMPACT | info | every request | the trade moves the price at least 3% and less than 10% (detail: the impact) |
LOW_LIQUIDITY | info | every request | under Orblivion's liquidity floor for its tier |
NO_REFERENCE | info | every request | no independent price reference; the exact simulation and the minimum output protect the trade |
STALE_REFERENCE | info | every request | the token's price reference is older than its maximum age |
UPGRADEABLE | info | every request | the token is a proxy whose code its admin can change |
PAUSABLE | info | every request | an admin can pause transfers |
PAUSED | info | every request | transfers are paused now, so trades will fail simulation |
BLOCKLIST | info | every request | an admin can block addresses from transferring |
ADMIN_BURN | info | every request | an admin can burn or seize balances |
SCALED_BALANCE | info | every request | balances are scaled (ERC-8056 multiplier or rebasing) |
CREATOR_TAX | info | every request | the creator takes a tax on curve trades |
CURVE | info | every request | still on its launch curve |
NEW_TOKEN | info | every request | launched in the last 24 hours |
HOOK | info | every request | a v4 hook outside Orblivion's known list is on the route; it can't change amounts |
UNVERIFIED | info | Shield only | Dossier hasn't found an official channel that claims this contract |
The same table is risks in GET /api/v1/config ({code: severity}), and the SDKs pin it: a server that publishes anything else, or answers with a code they don't know or a severity other than this table's, is refused (CONFIG_MISMATCH, RISK_CODES).
What a screen does and doesn't tell you#
A record says what Orblivion's screen saw: the address is an ERC-20 contract read on chain; a small buy and its sale back in simulation, from a fresh address, at the time of the screen; which hooks sit in its pools and what their permissions allow; how much liquidity it confirmed on chain; whether the token imitates a core asset; and what its code can do (upgrade, pause, block addresses, burn balances).
It does not say that the token is worth anything, that its deployer won't change it after the screen, that a sale will work for every wallet and every size, or that its pool isn't being pushed. A proxy whose code changes is screened again before it trades (TOKEN_CHANGED until then), and every trade is simulated again just before it is signed, but a token can behave differently for your wallet than for the screen's.
Hooks#
Uniswap v4 pools can carry a hook, a contract that runs around each swap. A hook Orblivion knows (none, the Pons graduation hook, and a short list of dynamic-fee hooks) passes silently. Any other hook is still a venue, disclosed from the permission bits in its own address:
AMOUNT_HOOK(severe) when it can change the swap's amounts:beforeSwapReturnDeltaorafterSwapReturnDelta, orbeforeSwapon a dynamic-fee pool, where it can set the fee as the swap executes;HOOK(informational) otherwise.
The SDKs and the co-signer read the class from the address themselves and refuse a plan whose hook Orblivion didn't disclose, an AMOUNT_HOOK you didn't accept, and any hook data. The minimum output holds either way.
Accepting risks#
A severe disclosure stops an executable plan unless the request names it:
{"wallet": "0x...", "token_in": "ETH", "token_out": "0x...", "notional_usd": 5, "accept_risks": ["TRANSFER_TAX"]}Without it, the plan is refused:
{"error": {"code": "RISK_NOT_ACCEPTED",
"message": "this trade carries severe risk the request doesn't accept: TRANSFER_TAX (pass accept_risks to trade anyway)",
"unaccepted": ["TRANSFER_TAX"],
"risks": [{"code": "TRANSFER_TAX", "severity": "severe", "detail": "..."}],
"terms": {"accept_risks": [], "shield": false, "source": "request", "...": "..."}}}accept_riskstakes severe codes only. An informational code there, an unknown code, or a code both accepted and blocked by a Shield policy is400 BAD_REQUEST.- A quote never refuses for risk: it only discloses. Acceptance matters for
prepare,build,simulatewith your wallet, and session grants. - The SDKs never accept anything on their own, and check again before they sign: a plan or a token record whose severe risks you didn't accept is refused locally (
RISK_NOT_ACCEPTED), whatever the server said. - Accepting a risk loosens no check that protects the trade. The exact call, the minimum output, the price references and the SDKs' own floors stay the same. Accepting
HIGH_PRICE_IMPACTlets a trade with high impact be planned; it doesn't widen your slippage. Setslippage_bpsyourself if you mean to trade through it. - For sessions and hosted agents the owner accepts, not the agent. The accepted risks are part of what the owner signs (see Sessions); a session trade that names other terms is refused (
SESSION_TERMS).
Dossier Shield#
Dossier is a verdict service for Orbio agent and Pons tokens: it checks whether the project behind a token's name officially claims this contract, or presents another one. Shield brings its verdict into your trades, for 0.10% more.
| Without Shield | With Shield | |
|---|---|---|
| Orblivion's fee | the schedule: 0.25% on a major trade (less at higher volume), 0.50% on any other | 0.10% (10 bps) more, taken the same way, in the same transaction: 0.35% on a major trade (or its tier plus 0.10%), 0.60% on any other |
| Dossier's verdict | not fetched, not shown (shield_available: true) | dossier: {verdict, url}, plus the IMPERSONATOR (severe) and UNVERIFIED disclosures |
| Policies that refuse instead of disclosing | none | block_impersonators (on by default), verified_only, block_risks |
| When Dossier can't be read | nothing waits on it | the trade is refused, 503 DOSSIER_UNAVAILABLE, with Retry-After; never treated as verified |
Turn it on per request with "shield": true, and set its policies under policies (policies without Shield are a 400):
{"token_in": "ETH", "token_out": "0x...", "notional_usd": 5, "wallet": "0x...",
"shield": true,
"policies": {"block_impersonators": true, "verified_only": false, "block_risks": ["HONEYPOT", "TRANSFER_TAX"]}}block_impersonatorsrefuses a token Dossier calls an impersonator: the project behind its name presents another contract. On by default with Shield. To trade one anyway, turn it off and acceptIMPERSONATOR.verified_onlyrefuses any token Dossier hasn't verified (impersonators, unverified and unknown ones). The core, stock and bridged assets Orblivion pins count as verified.block_risksrefuses any of the listed codes outright, accepted or not.
A refusal names the policy:
{"error": {"code": "RISK_BLOCKED", "message": "Dossier Shield's block_impersonators refuses this trade: IMPERSONATOR",
"blocked": ["IMPERSONATOR"], "policy": "block_impersonators", "policies": ["block_impersonators"]}}GET /api/v1/tokens/<address>?shield=1 shows the verdict on a token for free; the fee applies to trades only.
The SDKs and the fee. shield: true is your consent to Shield's 0.10%. Without it the SDKs accept only the schedule's rates without Shield for the trade's class (10, 15 or 25 bps on a major trade, exactly 50 on any other), so a Shield fee you didn't ask for never gets signed. With it, they require the Shield rates (20, 25 or 35 bps on a major trade, exactly 60 on any other), and a Shield trade of a token by address must carry Dossier's verdict (DOSSIER_VERDICT). Either way the fee is at most your maxFeeBps when you set one (FEE_BPS).
What Shield does and doesn't guarantee#
- It does add an independent check of the one thing a screen can't see: whether a token is the project's own. And it makes the policies you choose binding: a trade they refuse isn't built, and a session whose owner chose them can't be talked out of them.
- It doesn't make a token safe, liquid or worth anything. A verified token can still fall to zero, be paused, or tax transfers; the other disclosures still apply.
- Dossier's verdict is Orblivion's word. The SDKs require it to be present and allowed by your policies, but they can't check it themselves: a compromised server could report
verifiedfor an impersonator. A verdict signed by Dossier is future work. - Dossier can be wrong, or not know a token yet (
unknown, disclosed asUNVERIFIED). - Shield doesn't change the minimum output, the price checks or anything else that protects the trade. Those are the same for everyone.
Stock tokens#
NVDA, SPY and Robinhood Chain's other stock tokens are tokenized equities.
- They are not offered to US persons. The contracts don't enforce it, so Orblivion asks for the owner's statement: a stock trade needs
owner_attests_non_us: true(GEOFENCEotherwise). The SDKs send it only when you set it. The statement is yours and must be true; further eligibility checks may be added at any time. See the Terms of Use. - They can be paused, and their registry can block wallets: Orblivion checks both before building (
STOCK_PAUSED,WALLET_BLOCKED). - Pools trade around the clock while the stock price feeds stop for the weekend, so a weekend price may be stale (
STALE_REFERENCE). - Balances are scaled by a share multiplier (
SCALED_BALANCE). The price feeds already include it. - A hosted agent trades them only when it is live and its owner has signed the non-US attestation for its session, and only while the US stock-token session is open. See Hosted agents.