Biscotti — a DEX built from the math up
Biscotti is a decentralized exchange on Arc, Circle's stablecoin-native L1. Not a fork with a new logo: the V3 math, the smart-order router, the subgraphs and the contracts were all built and deployed as one system.
The interesting constraint: on Arc, gas is USDC. The chain has no volatile native token, which quietly breaks assumptions baked into every AMM codebase — starting with WETH.
Live AppTech Stack: Solidity · Foundry · React Router 7 · TypeScript · viem / wagmi · Cloudflare Workers · The Graph · Turborepo · Tailwind CSS
What's In It
| Swap | Smart-order routing that quotes V3 and StableSwap separately, then takes the best executable price |
| Liquidity | Uniswap V3-style concentrated positions, plus a StableSwap curve for correlated pairs |
| Earn | MasterChef farms, single-stake Coffee Pools |
| Launchpad | Fair token launches — liquidity live from the first block, LP locked by contract |
| Battles | On-chain trading competitions with a subgraph-backed leaderboard |
| Info | TVL, volume, fees and per-pool analytics from a self-hosted indexer |
Design Choices Worth Defending
Gas is USDC, so the wrapped-native model had to go. Arc's USDC is dual-interface — native for gas at 18 decimals, ERC-20 for everything else at 6. Every AMM assumes one canonical wrapped native. I made the routing layer speak ERC-20 only and treat the 18-decimal form as a gas detail, because mixing them in pool math is a rounding bug you find in production.
The router never quotes what it can't execute. The deployed routers are single-protocol — one understands V3 pools, the other StableSwap. A blended route prices better and then reverts. So the quote layer asks each protocol independently and keeps the best executable trade. Approval targets are resolved from the same function that builds the calldata, so it's structurally impossible to approve one router and swap against another.
Monorepo split by capability, not by app. Fourteen packages — v3-sdk, smart-router, swap-sdk-core, tokens, chains — consumed by one React Router 7 frontend and six Cloudflare Workers. The SDKs are unit-tested away from any UI, which is the only reason tick math and price impact are trustworthy.
Indexing is mine. Routing, analytics, farms and the launchpad each run as a Worker in front of The Graph, so the frontend never waits on a cold subgraph to render a price.
Status
Live on Arc Testnet with real pools, real trades and real TVL. Mainnet follows Arc's.
Currently building AgentPay — pay a merchant's invoice link in USDC, with an agent that reads your balances and routes whatever you hold into the exact amount owed.