ouroborai includes four Stylus (Rust) contracts compiled to WASM for
10-100x gas savings on computation-heavy operations. This guide covers
deploying them to Arbitrum Sepolia for testing.
Prerequisites
Rust toolchain with wasm32-unknown-unknown target
cargo-stylus CLI (cargo install cargo-stylus)
cast from Foundry for contract interaction
A funded Arbitrum Sepolia wallet (ETH for gas)
Contracts Overview
Contract Purpose Tests agent-registryOn-chain agent registry with capabilities bitmask 7 liquidation-monitorMulti-protocol lending health scanner 43 route-optimizerMulti-DEX route comparison engine 38 timeboost-vaultBid funding and express lane resale payments 27
Deployment
Run tests locally
Before deploying, confirm all 115 Rust tests pass: cargo test --features stylus-test \
--manifest-path contracts/Cargo.toml
All four contracts share a workspace Cargo.toml and use the
stylus-test feature flag for test utilities.
Validate with cargo-stylus
Check that the contract compiles to valid Stylus WASM. Run this for each
contract: agent-registry
liquidation-monitor
route-optimizer
timeboost-vault
cargo stylus check \
--manifest-path contracts/agent-registry/Cargo.toml \
--endpoint https://sepolia-rollup.arbitrum.io/rpc
Each check validates the WASM binary size, ABI compatibility, and
entrypoint structure against the Stylus runtime.
Deploy each contract
Deploy using cargo stylus deploy. You need a private key with Sepolia
ETH: agent-registry
liquidation-monitor
route-optimizer
timeboost-vault
cargo stylus deploy \
--manifest-path contracts/agent-registry/Cargo.toml \
--endpoint https://sepolia-rollup.arbitrum.io/rpc \
--private-key 0xYOUR_PRIVATE_KEY
Each command outputs the deployed contract address. Save these addresses
for the initialization step.
Initialize deployed contracts
After deployment, each contract must be initialized. Use cast send from
Foundry: agent-registry
liquidation-monitor
route-optimizer
timeboost-vault
# AgentRegistry needs governance set
cast send AGENT_REGISTRY_ADDRESS \
" set_governance(address) " YOUR_GOV_ADDRESS \
--rpc-url https://sepolia-rollup.arbitrum.io/rpc \
--private-key 0xYOUR_PRIVATE_KEY
Each contract can only be initialized once. Calling initialize a second
time reverts with “already initialized”.
Register protocols (LiquidationMonitor and RouteOptimizer)
After initialization, register the protocols and DEXes each contract should
monitor: # Add Aave V3 to the liquidation monitor (type 0 = Aave V3)
cast send LIQUIDATION_MONITOR_ADDRESS \
" add_lending_protocol(address,uint64) " \
AAVE_V3_POOL_ADDRESS 0 \
--rpc-url https://sepolia-rollup.arbitrum.io/rpc \
--private-key 0xYOUR_PRIVATE_KEY
# Add Uniswap V3 Quoter to route optimizer (type 0 = UniV3)
cast send ROUTE_OPTIMIZER_ADDRESS \
" add_dex(address,uint64) " \
UNISWAP_V3_QUOTER_ADDRESS 0 \
--rpc-url https://sepolia-rollup.arbitrum.io/rpc \
--private-key 0xYOUR_PRIVATE_KEY
Verify with cast call
Confirm the contracts are functioning: # Check total registered agents
cast call AGENT_REGISTRY_ADDRESS \
" total_agents() " \
--rpc-url https://sepolia-rollup.arbitrum.io/rpc
# Check lending protocol count
cast call LIQUIDATION_MONITOR_ADDRESS \
" lending_protocol_count() " \
--rpc-url https://sepolia-rollup.arbitrum.io/rpc
# Check DEX count
cast call ROUTE_OPTIMIZER_ADDRESS \
" dex_count() " \
--rpc-url https://sepolia-rollup.arbitrum.io/rpc
Deploying to Mainnet
The process is identical for Arbitrum One mainnet. Replace the RPC endpoint:
--endpoint https://arb1.arbitrum.io/rpc
After mainnet deployment, update the contract addresses in
packages/sdk/src/chain.ts to wire them into the TypeScript adapters.
Store deployed contract addresses in a shared configuration file or
environment variables so all services reference the same deployment.