Skip to main content

Prerequisites

ANK is written in Rust and requires a Rust toolchain to build from source.
1

Install Rust

If you don’t have Rust installed, use rustup to install the latest stable toolchain:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
After installation completes, restart your terminal or run:
source $HOME/.cargo/env
Verify the installation:
rustc --version
cargo --version
ANK requires Rust 1.70 or later. If you already have Rust installed, update to the latest stable version:
rustup update stable
rustup default stable
2

Clone the repository

Clone the ANK source code:
git clone https://github.com/your-org/ank.git
cd ank
Replace your-org with the actual GitHub organization or user. If you received ANK as a source archive, extract it and navigate to the root directory instead.
3

Build the project

Build all workspace members using Cargo:
cargo build
This compiles:
  • Core libraries (accounting, engine, exec, protocol, risk, oracle, math)
  • Protocol implementations (aave-v3, lido, uniswap-v3, pendle, hyperliquid)
  • CLI binaries (ank-cli, optimize)
  • API server (ank-api)
For optimized release builds:
cargo build --release
Release builds are significantly faster at runtime but take longer to compile. Use release mode for production simulations and parameter sweeps.
4

Verify the installation

Test that the binaries are built correctly:
cargo run -p ank-cli --bin ank-cli -- --help
cargo run -p ank-cli --bin optimize -- --help
You should see the help text for each binary.

Available binaries

ank-cli

Main simulation runner. Executes strategies from YAML config files and outputs risk metrics.

optimize

Parameter sweep optimizer. Runs grid searches over strategy parameters and scores results.

Running the binaries

# Run a simulation
cargo run -p ank-cli --bin ank-cli -- --config apps/cli/examples/sim.yaml

# In release mode (faster)
cargo run --release -p ank-cli --bin ank-cli -- --config sim.yaml
Important: If you see error: cargo run could not determine which binary to run, always use --bin to specify which binary to execute:
  • cargo run -p ank-cli --bin ank-cli ... for simulations
  • cargo run -p ank-cli --bin optimize ... for optimization

Repository structure

The ANK workspace is organized into focused modules:
Core engine and utilities:
  • accounting/ — Balance tracking, token/user IDs, timestamp types
  • engine/ — Orchestration, tick management, fee policies
  • exec/ — Transaction execution with callback support
  • protocol/ — Protocol trait definition and action/event types
  • risk/ — Risk metrics calculation and CSV logging
  • oracle/ — Price path overrides for stress testing
  • math/ — Ray and wad math utilities (1e27 and 1e18 precision)
  • replay/ — Historical event replay
  • agents/ — Agent framework (WIP)
  • opt/ — Optimization scaffolding
Protocol implementations:
  • aave-v3/ — Aave V3 multi-asset lending (deposit/borrow/repay/withdraw/liquidate)
  • lido/ — Lido wstETH staking with exchange rate growth
  • uniswap-v3/ — Toy Uniswap V3 pool for swaps
  • pendle/ — Full Pendle PT/YT + SY wrapper + AMM
  • hyperliquid/ — Hyperliquid perpetuals (experimental)
Applications:
  • cli/ — Contains ank-cli and optimize binaries
  • api/ — REST API server for running backtests via HTTP (experimental)

Development workflow

Running tests

Run the full test suite:
cargo test
Run tests for a specific crate:
cargo test -p ank-protocol-aave-v3
cargo test -p ank-engine

Generating TypeScript bindings

ANK can export TypeScript type definitions for use in web frontends:
TS_RS_EXPORT_DIR="$(pwd)/bindings/types" cargo ts
This generates .ts files in bindings/types/ for all types annotated with #[cfg_attr(feature = "ts-bindings", derive(TS))].

Code formatting and linting

Format code:
cargo fmt
Run linter:
cargo clippy

Troubleshooting

Error:
error: cargo run could not determine which binary to run
Solution: Always specify the binary with --bin:
cargo run -p ank-cli --bin ank-cli -- --config sim.yaml
cargo run -p ank-cli --bin optimize -- --sweep sweep.yaml
Error:
invalid type: string "1_725_...", expected u64
Solution: Remove underscores from integer values in YAML files:
# ❌ Wrong
start_ts: 1_725_000_000

# ✅ Correct
start_ts: 1725000000
Error:
the trait `Serialize` is not implemented for `IndexMap<...>`
Solution: Ensure the serde feature is enabled for indexmap in Cargo.toml:
indexmap = { version = "2", features = ["serde"] }
This is already configured in the workspace Cargo.toml.
Error:
cannot borrow as mutable because it is also borrowed as immutable (E0502)
Solution: When implementing protocols, avoid holding multiple mutable and immutable borrows simultaneously:
// ❌ Wrong: holding reserve reference while modifying user
let reserve = &self.reserves[&token];
let user = &mut self.users[&user_id];

// ✅ Correct: clone values or split into separate blocks
let reserve_price = self.reserves[&token].price;
let user = &mut self.users[&user_id];
Error:
HF violation: post-withdraw HF would be below 1.0
Solution: This is intentional behavior. Aave’s withdraw enforces that the health factor remains ≥ 1.0 after the withdrawal. Either:
  • Reduce the withdrawal amount
  • Repay some debt before withdrawing
  • Deposit additional collateral

Next steps

Quick start

Run your first simulation with the Lido ↔ Aave leverage example

Configuration reference

Learn about all available config options for sim.yaml

Protocol APIs

Explore the action schemas for each protocol

Strategy development

Build custom strategies using the planner pattern

Build docs developers (and LLMs) love