AI-recommended, self-executed liquidity routing for Robinhood Chain Stock Tokens. Chain ID 4663.
SPHINX separates recommendation from execution. Three signers, three roles. The agent's key is isolated — it can only call publishRecommendation, a pure event-emitting function with zero fund movement.
The core router. Registers venue adapters, compares live quotes, publishes agent-gated recommendations, and executes user-authorized swaps under on-chain guardrails.
| Function | Caller | Description |
|---|---|---|
| registerVenue(address) | owner | Add a venue adapter to the router's registry |
| bestVenue(tokenIn, tokenOut, amountIn) | anyone (view) | Compare live quotes across all active venues for a pair |
| publishRecommendation(...) | agent only | Emit Recommendation event — no custody, no execution |
| executeSwap(venueId, tokenIn, tokenOut, amountIn, minAmountOut) | anyone | Execute swap with full guardrail checks |
| setPairGuardrails(tokenIn, tokenOut, maxSize, slippageBps, refDeviationBps) | owner | Configure per-pair safety parameters |
| setReferenceFeed(tokenIn, tokenOut, feed) | owner | Wire a Chainlink price feed for a pair |
| revokeAgent() | owner | Disable the agent's ability to publish |
| removeVenue(index) | owner | Remove a venue and compact the array |
Wraps any Uniswap V2-style DEX router into the IVenueAdapter shape. Implements quote() via getAmountsOut and swap() via swapExactTokensForTokens. Use as a template for wrapping Arcus, RFQ desks, or any other venue.
Every protection sits on-chain, per trading pair, enforced by the router — not by trusting the frontend.
| Guardrail | Mechanism | Protects against |
|---|---|---|
| Slippage floor | minAmountOut too loose → rejected on-chain | Sandwich attacks, frontend bugs |
| Oracle deviation | Quote vs Chainlink ≤ threshold | Manipulated venue quotes |
| Order size caps | Per-pair maxOrderSize | Liquidity crushing, whale exploits |
| Agent key isolation | Agent signer ≠ executor signer | Compromised agent moving funds |
| Reference staleness | Chainlink updatedAt check | Stale oracle data |
Deploy to Robinhood Chain mainnet (chain ID 4663). Requires DEPLOYER_PRIVATE_KEY and the agent's address as constructor argument.
forge create contracts/SPHINX.sol:SPHINX \
--rpc-url https://rpc.mainnet.chain.robinhood.com \
--private-key $DEPLOYER_PRIVATE_KEY \
--constructor-args $AGENT_ADDRESS \
--broadcast
Verify on Blockscout →
The agent lives in agent/. It polls bestVenue() across configured pairs on a schedule, compares results against a live Chainlink reference price, and calls publishRecommendation with a human-readable reason string. Its private key is separate from any execution-capable key.
cd agent
cp .env.example .env
# Set AGENT_PRIVATE_KEY, RPC_URL, ROUTER_ADDRESS
node src/index.js