Tuo docs

Roles and admin controls

Every on-chain role in Tuo, what each can and cannot do, and the boundaries that keep customer funds inside the position.

Tuo uses OpenZeppelin AccessControl with three roles. The vault wires their administration in its constructor, and the super-admin role is never granted, so there is no single key that can reconfigure the system.

Actors

ActorOn-chain identityCan doCan never do
CustomerOwner of the position NFTdeposit, requestWithdraw, withdraw, emergencyWithdraw, transfer the NFTAnything else. Ownership of the NFT is the whole authority model
TreasuryTREASURY_ROLE, a 2-of-3 Safe with hardware-wallet signersGrant and revoke KEEPER_ROLE and PAUSER_ROLE, rotate itself, set the fee recipient, sweep accrued fees, set the per-position cap, maintain the Hyperliquid operator allowlist, register and retire products, add and retire aggregators, set the NFT base URIChange the fee percentage, upgrade anything, touch a position, reach a deployed liquidity position, move idle balances, stop a withdrawal
KeeperKEEPER_ROLE, an EOA whose key is held in a cloud HSMReshape a position's holdings inside the vault (swapIdle, mintLp, burnLp), send hedge margin to the position's bound operator (bridgeToHl), pull it back or attest a final return (markBridgeInboundComplete), settle an emergency claim (settleHlClaim)Cause funds to rest anywhere but the vault, the Uniswap position manager, the bound operator, or the NFT owner. Exceed 10 metered actions or 150 bps of basis in measured loss per position per 24 hours
PauserPAUSER_ROLE, a dedicated hardware walletpauseDeposits, unpauseDepositsAffect withdrawals or emergency exits in any way
Hyperliquid operatorOne EOA per position, on the treasury allowlist, key in a cloud HSMReceive bridged margin, act as the position's Hyperliquid account, approve the vault to pull margin backCall the vault. It is a destination and a pull source, never a caller
AggregatorAddress on the router allowlistBe the target of one call per swap, with an exact-amount approval cleared immediately afterHold funds across calls or receive an open-ended approval

Trust boundary

Every arrow into the vault is bounded by a role check. Every arrow out of the vault goes to one of four destinations: the owner, the Uniswap position manager, an allowlisted aggregator inside one atomic swap, or the position's bound Hyperliquid operator.

The treasury surface

FunctionNotes
setFeeRecipientZero address rejected
claimFees, claimTokenFeesPull payment. Reverts on a zero balance. A broken recipient blocks Tuo's revenue, never a customer's exit
setPerNftCapZero rejected. Bounds one position's basis and nothing else. No aggregate cap exists on-chain
setHlOperatorAdds or removes an operator from the allowlist. Never unbinds a position that already bridged to that operator
registerProduct, setProductOpenAdd-only registry. Retiring a product blocks new positions only
addAggregator, removeAggregatorForwarded to the router. Emptying the list stops non-USDC deposits and the exit swap, never the USDC exit or the emergency exit
setBaseURICosmetic. No custody or accounting reads it

Role administration

  • DEFAULT_ADMIN_ROLE is never granted. The deployment script asserts that nobody holds it.
  • TREASURY_ROLE administers itself, KEEPER_ROLE and PAUSER_ROLE.
  • TREASURY_ROLE cannot be renounced or self-revoked. If the last holder could give the role up, nobody could ever revoke a compromised keeper again. Rotation is grant, then the new holder revokes the old one.
  • KEEPER_ROLE and PAUSER_ROLE are rotatable by the treasury at any time.

Pausing

pauseDeposits stops new deposits and top-ups. It does not affect requestWithdraw, withdraw or emergencyWithdraw, and it does not stop the keeper from unwinding a position. It is a circuit breaker on inflows only, held by a single hardware wallet so it never waits on two signatures.

Residual risks in this model

These are disclosed design decisions, listed in full on Audits.

  • The Hyperliquid operator set is treasury-mutable, and the vault does not enforce one operator per position. That rule is off-chain discipline. Each position binds to the operator it first bridged to and never rebinds, and both inbound legs pull only from that operator.
  • A compromised treasury could retire every aggregator but one it controls. That is a smaller power than the one it already holds over the keeper role, and it cannot touch the guaranteed exits.
  • The 150 bps per day loss budget compounds to roughly 36% of a position in a month. Detection and the Safe revoking the keeper are the real bound. See Operational risk.

On this page