Rug pulls stole $2.8 billion from crypto users in 2024 alone. The frustrating part? Most of the warning signs are sitting right there on-chain — concentrated holder wallets, unverified contracts, hidden mint functions, honeypot patterns. But reading a smart contract or navigating block explorers isn't realistic for most people.
We wanted to build the tool we wished existed when a friend lost money on a token that "looked legit." Something where you paste an address, and it just tells you the truth — no jargon, no dashboards full of numbers you don't understand. Just: here's the score, here's why, here's what to watch out for.
How We Built It
We started with the scoring model. Before writing a single line of UI code, we mapped out the six signal categories that best predict rug pulls based on post-mortem analyses of known scams: holder concentration, liquidity depth, token age, contract verification, admin/owner control, and honeypot indicators. Each category has weighted thresholds tuned against known-good tokens (USDT, USDC) and known-bad patterns.
The backend is a FastAPI service that fires off three API calls in parallel — DexScreener for market data, Etherscan V2 for contract verification and source code heuristics, and GoPlus Security for honeypot detection and holder analysis. We use asyncio.gather so all three resolve concurrently, keeping response times under 3 seconds even though we're hitting three different services. If any API fails, the others still contribute — graceful degradation was a core design principle.
The frontend is a Next.js app with a dark, card-based UI. The score gauge is a hand-built SVG arc with a cubic ease-out animation. Every detail card is collapsible. The loading state cycles through progress messages so users know the app is actually working, not stuck. We were deliberate about making it feel like a real product, not a hackathon prototype.
Challenges We Faced
GoPlus returns everything as strings. Booleans are "1" and "0", percentages are decimal strings like "0.312" meaning 31.2%, taxes are "0.05" meaning 5%. Every field needed careful type coercion, and getting even one wrong meant wildly inaccurate scores. We caught a bug where tax values were being displayed as decimals instead of percentages — a 5% sell tax was showing as 0.05%.
Scoring calibration was harder than expected. Our first pass flagged USDT as HIGH risk because Tether's contract legitimately has mint, pause, and blacklist functions. We had to rethink the weighting so that admin flags alone don't dominate the score — a token with admin controls but deep liquidity, millions of holders, and years of history shouldn't score the same as a 2-day-old token with the same flags.
CORS across three deployment targets. Getting a FastAPI backend on Render to accept requests from a Vercel-hosted frontend with the right origin patterns required regex-based CORS configuration — wildcard subdomains don't work with CORSMiddleware out of the box.
Render free tier cold starts. The backend spins down after inactivity, so the first request after idle takes ~30 seconds. We added a TTL cache layer so at least repeat queries for the same token are instant, and the frontend loading skeleton with cycling progress messages keeps users from bouncing during the wait.
What We Learned
- On-chain data is messy. Every API has its own ID scheme for chains, its own response format, its own quirks. Normalizing three different data sources into one clean model was half the engineering work.
- Explainability matters more than the number. Users don't trust a score unless they can see why. The reasons list ("Top 5 holders control 82% of supply") is what actually builds confidence in the tool.
- Parallel async I/O in Python is genuinely fast. Three network-bound API calls that would take 6+ seconds sequentially resolve in under 2 seconds with asyncio.gather.
Built With
- asyncio;-apis:-dexscreener
- etherscan-v2
- fastapi
- frontend:-next.js-14
- github
- goplus-security;-caching:-cachetools-(in-memory-ttl);-hosting:-vercel-(frontend)
- httpx
- pydantic
- react-18
- render
- repository:
- tailwind-css;-backend:-python-3.11
- typescript
Log in or sign up for Devpost to join the conversation.