bugglo
v0.4.0
Published
Read Robinhood Chain (4663) directly: rug checks, ownership, upgradeable-proxy and privileged-function disclosure. No API key, no account, no backend. Reports UNKNOWN as a first-class result — a check that did not run is never a check that passed.
Maintainers
Readme
bugglo
Robinhood Chain (4663), read straight from the chain. No API key, no account, no backend.
bugglo is a terminal and library for asking the questions a holder asks before touching a token:
- Does code exist at this address on Robinhood Chain, not Ethereum by accident?
- Does it look like an ERC-20?
- Is ownership renounced, active, or simply not visible through
owner()? - Is it an EIP-1967 upgradeable proxy?
- Which common privileged selectors are present in bytecode?
- Is there DEX liquidity, real sell flow, and enough depth to matter?
- Which checks could not run, and why?
It deliberately reports UNKNOWN as a first-class result. A check that did not run is never a check
that passed.
Quick start
npx bugglo 0x2103faA9D1762e27a716C61718b3aCf3Ec1F9bf1Machine-readable output:
npx bugglo --json 0x2103faA9D1762e27a716C61718b3aCf3Ec1F9bf1Use your own RPC:
npx bugglo --rpc https://your-robinhood-chain-rpc.example 0x2103faA9D1762e27a716C61718b3aCf3Ec1F9bf1Use fallback RPCs:
npx bugglo --rpc-list https://rpc.one,https://rpc.two 0x2103faA9D1762e27a716C61718b3aCf3Ec1F9bf1Commands
| Command | Output |
|---|---|
| bugglo <address> | Full rug-check report. |
| bugglo rug <address> | Same as above. |
| bugglo gate <address> | Pre-trade firewall: ALLOW / BLOCK / UNKNOWN, reasons worst-first. Exits 0 only on ALLOW. |
| bugglo exit <address> | Read-only full-exit simulation: does a sell actually clear? |
| bugglo deployer <address> | Who created this token, and what else they have shipped. |
| bugglo deployed <address> | Every contract an account created with CREATE, newest first. |
| bugglo concentration <address> | Where the nameable supply sits. Not a holder distribution — see below. |
| bugglo rwa <address> | Official Robinhood stock token, or an impostor wearing its ticker? |
| bugglo info <address> | ERC-20 metadata, bytecode size, and per-field metadata errors. |
| bugglo ownership <address> | renounced, owned, or no-owner-fn. |
| bugglo proxy <address> | EIP-1967 implementation slot status. |
| bugglo powers <address> | Common privileged function selectors found in deployed bytecode. |
| bugglo market <address> | DexScreener liquidity, FDV, volume, buy/sell counts, pool age, and ratios. |
| bugglo limits | Checks this package cannot perform from bare RPC + public DEX data. |
Deployer forensics, without an indexer
bugglo deployer answers "who is behind this, and what else have they shipped?" from a bare RPC.
It recovers the token's origin transaction from its earliest mint, then proves the link
arithmetically — a CREATE address is keccak256(rlp([sender, nonce])), so a candidate either
derives to the token or it does not.
| Status | Meaning |
|---|---|
| PROVEN | This account created this token. Derived, not inferred. |
| VIA-FACTORY | A launchpad deployed it. Names both the factory and the human who signed and paid. |
| NOT-THE-DEPLOYER | A candidate's full history was walked and this token is not in it. |
| UNKNOWN | No candidate could be recovered, or the walk could not be completed. |
A walk that did not finish never returns a negative — an incomplete search reporting "no" is a fabrication with extra steps. Contracts deployed through a factory, or since self-destructed, are invisible to a nonce walk, and that limitation ships on every result.
concentration is not a holder distribution
Read this before using it, because the failure mode of this command is reassurance.
A real holder distribution needs an indexer, and this chain has none — a full-range Transfer
query against chain 4663 times out, and so does a 1M-block window. That check stays UNMEASURABLE.
What bugglo concentration does instead is partition the supply across addresses it can name
— the launcher, the owner, the factory, every DEX pool, the burn sinks, the token contract — and
report everything left over as UNACCOUNTED. That remainder is genuinely unknown: it may be ten
thousand independent buyers, or one wallet the launcher opened an hour before the launch. Those
are indistinguishable from here.
So the number to read first is the one it prints first. A low insider balance is not evidence of a fair launch — moving a bag to a fresh address costs one transaction, and that address looks exactly like a buyer to this method.
Options:
--json Print JSON where supported
--full Print the full address in the rug-check report
--rpc <url> Override the Robinhood Chain RPC
--rpc-list <urls> Comma-separated fallback RPC URLs; first healthy chain 4663 endpoint wins
--timeout <ms> Chain RPC timeout
--dex-timeout <ms> DexScreener timeout
--no-color Disable ANSI colour
--help Show help
--version Show versionExample report
BUGGLO — rug check
Robinhood Chain (chain 4663)
0x2103...9bf1
Robin Hood (FOX), 18 decimals
VERDICT NO RED FLAGS IN WHAT I COULD CHECK
UNKNOWN Ownership unclear
There is no standard owner() function. That does NOT mean ownership is
renounced — the contract may use roles or an embedded admin that I cannot see.
PASS Contract exists
4,830 bytes of bytecode on Robinhood Chain (chain 4663).
PASS Full exit simulation cleared
A funded synthetic holder completed a full sell through the pool and
received value back, at this block and at this size. Not a promise.
NOT CHECKED — these are not passes
holder concentration
liquidity lockThe verdict is intentionally wordy. Rounding it up to "safe" is the bug this package exists to avoid.
Library API
import { rugCheck, ROBINHOOD_CHAIN_ID } from "bugglo";
import { renderRugCheck } from "bugglo/report";
const result = await rugCheck("0x2103faA9D1762e27a716C61718b3aCf3Ec1F9bf1");
console.log(ROBINHOOD_CHAIN_ID);
console.log(renderRugCheck(result));Available exports:
import {
ROBINHOOD_CHAIN_ID,
RPC_URL,
UNMEASURABLE,
rugCheck,
getContractCode,
getTokenMetadata,
getOwnership,
getProxyStatus,
getMarket,
scanPowers,
} from "bugglo";
import { renderRugCheck, renderDeployer, renderGate, renderOneLine } from "bugglo/report";
import { tradeGate } from "bugglo/gate";
import { simulateExit, simulateSell } from "bugglo/simulate";
import { traceDeployer, deployedContracts, findCreation } from "bugglo/deployer";
import { verifyAgainstRegistry, officialList, REGISTRY_META } from "bugglo/registry";The gate is the one to reach for if you are wiring this into anything that can spend money:
import { tradeGate } from "bugglo/gate";
const decision = await tradeGate(token, { side: "buy" });
// ALLOW = no blocker was PROVEN. Never "safe".
// UNKNOWN = safety could not be proven — treat it exactly like BLOCK before auto-executing.
if (decision.decision !== "ALLOW") return escalateToHuman(decision.reasons);Network and reliability
By default, bugglo talks to:
| Host | Used for |
|---|---|
| rpc.mainnet.chain.robinhood.com | Bytecode, owner(), ERC-20 metadata, storage slots. |
| api.dexscreener.com | Liquidity, volume, FDV, buys, sells, pool age. |
The public Robinhood Chain RPC is free and convenient, but public RPCs can be rate-limited, blocked by some ISPs, or unavailable from some networks. For bots, CI, trading desks, and public services, use a dedicated provider endpoint:
ROBINX_RPC_URL=https://robinhood-mainnet.g.alchemy.com/v2/YOUR_KEY npx bugglo <address>Or pass several endpoints:
BUGGLO_RPC_URLS=https://rpc.one,https://rpc.two npx bugglo <address>DNS-blocked networks (e.g. Indonesia's Trust Positif filter)
The chain RPC lives on a robinhood.com subdomain, and some ISPs block that domain at the DNS
level — Indonesian networks running the government Trust Positif filter answer the lookup with the
filter's server instead of the chain. The endpoint is not geo-blocked; only its name is poisoned.
bugglo handles this automatically. When a direct connection fails, it re-resolves the host over
DNS-over-HTTPS (which the ISP resolver cannot poison) and connects to the real IP, with TLS SNI and
certificate validation still pinned to the true hostname. No VPN, no DNS change, no flag, no API key.
If the DoH resolvers are themselves blocked, fall back to --rpc/ROBINX_RPC_URL on an unblocked
domain, or a VPN.
If every path fails, Bugglo reports CANNOT CHECK / UNKNOWN. It does not turn an outage into a
clean verdict.
What it will not fake
These checks are always disclosed as not measured:
| Check | Why |
|---|---|
| Holder concentration | Needs an indexer. Reconstructing balances from all Transfer logs is not viable at CLI latency on a public RPC. |
| Liquidity lock | Needs a known locker registry for this chain. |
No numeric risk score is emitted. A score made from partial data launders ignorance into confidence.
MCP
For agents, use the companion package:
{
"mcpServers": {
"bugglo": {
"command": "npx",
"args": ["-y", "bugglo-mcp"]
}
}
}bugglo-mcp is only an adapter. The chain logic lives here, in bugglo, so CLI, library, and MCP
answers cannot drift.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Command completed. The result may still contain WARN or UNKNOWN; read it. |
| 1 | The requested check could not complete, or the RPC proved wrong/unusable. |
| 2 | Bad CLI usage, malformed address, or invalid option. |
License
MIT.
