Skip to main content
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)
Get Sepolia ETH from the Arbitrum Sepolia faucet or bridge from Ethereum Sepolia via the Arbitrum bridge.

Contracts Overview

ContractPurposeTests
agent-registryOn-chain agent registry with capabilities bitmask7
liquidation-monitorMulti-protocol lending health scanner43
route-optimizerMulti-DEX route comparison engine38
timeboost-vaultBid funding and express lane resale payments27

Deployment

1

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.
2

Validate with cargo-stylus

Check that the contract compiles to valid Stylus WASM. Run this for each contract:
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.
3

Deploy each contract

Deploy using cargo stylus deploy. You need a private key with Sepolia ETH:
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.
4

Initialize deployed contracts

After deployment, each contract must be initialized. Use cast send from Foundry:
# 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”.
5

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
6

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.