Architecture
The three Tuo contracts, the libraries behind them, their external dependencies, and the invariants the test suite holds them to.
Tuo deploys exactly three contracts, all in one transaction. TuoVault's constructor deploys
TuoPositionNFT and TuoSwapRouter itself and wires every role, so there is no window in which
the contracts are live but not yet configured.
Contracts
| Contract | Purpose |
|---|---|
TuoVault | Custody core. Deposit, withdrawal, emergency exit, the keeper surface, budgets, fee accrual, roles. One deployed contract split across four source files (TuoVault, TuoVaultViews, TuoVaultStorage, TuoVaultAdmin) |
TuoPositionNFT | Plain transferable ERC-721. ownerOf is the sole withdrawal authority. Mint and burn are vault-only. There is no recipient gate on transfer |
TuoSwapRouter | Vault-only execution wrapper for 0x and 1inch. Treasury-maintained aggregator allowlist, exact-amount approvals cleared after every call, balance-delta verification, strict full-spend of the input |
Internal libraries
| Library | Role |
|---|---|
TuoConstants | Every protocol parameter in one place. See Parameters |
TuoRoles | The three role identifiers |
PerformanceFee | Stateless 30%-of-profit math and the pro-rata basis reduction |
PoolTwap | 30-minute pool TWAP reads and the spot-versus-TWAP deviation gate |
PositionValuation | USDC value of a Uniswap V3 position at the TWAP tick |
LpBounds | Slippage floors for a V3 mint |
Topology
External dependencies
| Dependency | Version or address | Used for |
|---|---|---|
| OpenZeppelin Contracts | 5.6.1 | AccessControl, ERC-721, SafeERC20, ReentrancyGuard, Pausable |
| Uniswap v3-core | 1.0.2 (solc 0.8) | Pool interfaces and tick math |
| Uniswap NonfungiblePositionManager | Canonical per network | Minting, burning and collecting concentrated liquidity |
| 0x AllowanceHolder | Allowlisted aggregator | Entry and exit swaps |
| 1inch AggregationRouter v6 | Allowlisted aggregator | Entry and exit swaps |
| Circle CCTP v2 | Off-chain rail | Moving hedge margin between Arbitrum and Hyperliquid. The contracts never see which rail is used |
Compiler and build
| Setting | Value |
|---|---|
| Solidity | 0.8.26, pinned |
| EVM version | cancun |
| Optimizer | On, 200 runs, via_ir |
| Metadata | bytecode_hash = none, CBOR metadata off, to stay under the EIP-170 size limit |
TuoVault runtime size | 23,250 bytes, 1,326 bytes below the ceiling |
The metadata setting means explorer verification is a partial match rather than an exact match. The source still verifies.
Design rules
- No proxies, no upgrades. What is deployed is what runs, for the life of the deployment.
- No strategy on-chain. Range selection, hedge sizing and rebalance timing come from the off-chain engine and arrive as ordinary keeper calls. The chain's job is to keep every call inside a perimeter that cannot move funds away from the owner.
- No shared pot. Every asset in the vault is attributed to exactly one position. There is no pooled accounting and no share token.
- Measured-only settlement. The vault never values the Hyperliquid leg. Any settlement path reverts while margin is bridged out, so a fee can only be charged on value the vault can see.
- Checks, effects, interactions everywhere. The NFT is burned before any payout, and every external call happens after state is written.
- Pull-payment fees. Fees accrue in the vault and are swept by the treasury. A fee recipient that cannot receive USDC blocks Tuo's revenue, never a customer's exit.
Invariants
The test suite runs a stateful fuzz harness driven by a hostile keeper: floor-priced fills, dust bridges to two operators, dust-LP spam, attacker-routed swaps, and unrestricted position transfers between actors. These properties must hold after every sequence.
| Invariant | Property |
|---|---|
| I1, I2 | USDC and WETH are fully attributed: the vault balance equals the sum of idle balances plus accrued fees |
| I3 | A position's basis never exceeds what was actually deposited |
| I4 | Value is conserved across the whole lifecycle, summing both operators |
| I5 | The keeper is never enriched |
| I6 | An NFT exists if and only if its position is active or has an open Hyperliquid claim |
| I7 | The 10-action budget holds |
| I8 | The owner can always exit |
| I9 | Keeper-attributed loss stays inside the rolling budget |
| I10 | The Hyperliquid claim ledger is lossless |
Alongside the invariants there are 21 unit suites, access-control tests that assert the exact account and role, tests with authorized-but-hostile callers, and fork tests against the real Arbitrum position manager, pools and a real aggregator. 311 tests in total.
Source
The repository is private during the guarded launch. Verified source for every deployed contract is linked from Deployed addresses. The licence is on Licence.