Documentation
How to read and use the router.
Everything needed to verify the contracts, integrate against them, or decide not to. The limitations section is not a footnote — read it first if you are considering size.
Deployment
Addresses
| VunexRouter | not deployed |
| VunexVenue | not deployed |
| TokenFactory | not deployed |
| VunexBootstrap | not deployed |
| $vunex token | 0xa7d57caf9867cf10f4be9c36f2169d2af01b446e |
| vUSD (quote asset) | not deployed |
| Chain | Robinhood Chain · id 4663 |
| RPC | https://rpc.mainnet.chain.robinhood.com |
| Multicall3 | 0xcA11bde05977b3631167028862bE2a173976CA11 |
Identify contracts on this chain by ABI, never by name. Several look-alike contracts share each ticker here, and the canonical Ethereum mainnet Uniswap addresses both exist on 4663 holding unrelated code.
Integration
Placing an order
Approve the router for tokenIn, then call swapExactIn.
Legs must sum exactly to amountIn; the contract rejects anything else.
function swapExactIn(
SwapRequest calldata request, // tokenIn, tokenOut, amountIn,
// minAmountOut, recipient, deadline
Leg[] calldata legs // { venueIndex, amountIn }[]
) external returns (uint256 amountOut);
Compute the legs off-chain or read the book yourself. Three views expose everything the contract knows:
// what one venue returns for this size
function quoteVenue(address tokenIn, address tokenOut,
uint256 index, uint256 amountIn)
external view returns (uint256 amountOut);
// the benchmark your order must beat
function bestSingleVenue(address tokenIn, address tokenOut,
uint256 amountIn)
external view returns (uint256 bestOut, uint256 bestIndex);
// the whole book in one call: quotes, depth, fee tier, routability
function book(address tokenIn, address tokenOut, uint256 amountIn)
external view returns (uint256[] memory indices,
uint256[] memory amountsOut,
uint256[] memory depths,
uint16[] memory fees,
bool[] memory routable);
Venue indices come from venueCount and venueAt. They are
not stable: removeVenue swaps the last entry into the gap, so re-read
them after any registry change rather than caching.
The guarantee
What is actually proven
Before any leg executes, the router quotes every registered, routable venue for the pair at the full order size. After executing, it compares the fill against that benchmark:
if (amountOut < bestSingleVenueOut)
revert CannotProveBestExecution(amountOut, alternative, venueIndex);
Quoting happens before execution on purpose. Quoting afterwards would let someone move an unrelated pool inside the same block to manufacture a better-looking alternative and force your order to revert — cheap griefing.
There is no tolerance. A split settles only when it strictly beats the best single venue, which is the intended reading: a split that cannot beat single-venue routing has no reason to execute.
Every leg is validated — pair match and depth floor — before the router pulls any tokens, so a rejected order never moves your balance at all.
Curation
How a venue gets admitted
- Existence — the pool must really exist on the contract it claims.
- Fee tier — the declared tier must match what the pool reports.
- Pair — both token addresses are read off the venue, not supplied.
- Depth to route — it must absorb the depth floor of vUSD to move 1%.
- Depth to appear — none. A drained pool still shows.
One floor, not two, because reading a venue and routing to it are different jobs. Depth decides only what may receive an order. Nothing is hidden from the book for being thin — a pool that has drained to nothing and still advertises a price is the clearest example of the problem this exists to solve.
Depth is the quote notional required to move a venue's price by 1%, derived from
its reserves. Reserves are tracked inside the venue rather than read from
balanceOf, so a donation cannot move a quoted price and an off-chain
quoter reproduces every fill to the wei.
Read this part
Limitations
Every token here is synthetic and unbacked
vUSD and every ticker are ERC-20s that reference a listed security and are backed
by nothing. No custodian, no oracle, no redemption, no claim on the company. The
disclosure is in the bytecode: name() ends in "(synthetic, unbacked)"
and isSynthetic() returns true.
The listings and the opening prices are real — pulled from the Shanghai and Shenzhen tape at deploy time. The routing, the proof and the reverts are real and run on mainnet. The money is not.
Unaudited
Written and tested in a single session. 27 tests pass, including a 256-run fuzz asserting that a settled fill is never worse than the best single venue and that the router retains no balance afterwards. The whole deployment was rehearsed against a fork of mainnet, including a real routed fill and a real refusal. That is evidence, not an audit.
The proof is scoped to the registry
Best execution is proven against registered venues only. A pool outside the registry is not considered, so the guarantee is exactly as good as the curation — which is published, and driven by depth rather than by advertised price.
The owner curates
The owner can add and remove venues. Entries are validated against the venue contract, so a compromised owner cannot point your order at an invented pool, but they can still decide which pools are eligible.
Assertion gas scales with venue count
Every registered venue for the pair is re-quoted on every order. Three fee tiers per name keeps that cheap; a name carrying dozens of venues would not be.
Splitting rarely helps
Multi-leg routing exists and works, but on a penny name the cheapest venue is usually also the deepest, so the solver normally picks one venue. Splitting pays only on orders large enough to exhaust the best one.
US names are not listed
Nothing prices them keylessly any more — Yahoo and Stooq both stopped serving equity quotes without a key. Listing a name whose price cannot be honestly sourced would mean inventing one. The router is generic over any ERC-20 pair, so a US name lists the day there is a price for it.