Skip to main content

Overview

The ank-accounting module provides minimal accounting primitives used across the engine and protocols. All amounts are represented as 1e18-scaled integers (wei) unless otherwise stated.

Core Types

Timestamp

pub type Timestamp = u64;
Logical time unit (e.g., block/tick index) used throughout the simulation.

UserId

pub type UserId = u64;
Internal user identifier in simulations.

TokenId

pub struct TokenId(pub u32);
Identifier of a fungible token in the simulation.
0
u32
The numeric token identifier

Amount

pub type Amount = u128;
1e18-scaled unsigned quantity (e.g., wei). Represents token amounts with 18 decimal places of precision.

Balances

pub struct Balances(pub IndexMap<TokenId, Amount>);
Per-user balances: mapping from TokenId to Amount. This is a thin wrapper over IndexMap<TokenId, Amount> with helper methods for balance management. When the ts-bindings feature is enabled, this maps to Record<number, string> (amounts serialized as decimal strings).

Methods

get

pub fn get(&self, t: TokenId) -> Amount
Returns the current Amount for token t, or 0 if absent.
t
TokenId
required
The token identifier to query
return
Amount
The current balance for the token, or 0 if not present

set

pub fn set(&mut self, t: TokenId, v: Amount)
Sets the Amount for token t (overwrites any previous value).
t
TokenId
required
The token identifier to set
v
Amount
required
The new balance amount (1e18-scaled)

apply_delta

pub fn apply_delta(&mut self, delta: &BalancesDelta) -> Result<()>
Applies a signed BalancesDelta to these balances.
  • Positive deltas are added using saturating addition
  • Negative deltas are subtracted using saturating subtraction (no underflow)
delta
&BalancesDelta
required
The balance changes to apply
return
Result<()>
Always returns Ok(()) (reserved for future validation/errors)

BalancesDelta

pub struct BalancesDelta(pub IndexMap<TokenId, i128>);
Signed change to balances: mapping from TokenId to i128 delta.
  • Positive deltas add to balances
  • Negative deltas subtract from balances
  • Subtractions saturate at zero (no underflow panic)
When the ts-bindings feature is enabled, this maps to Record<number, string> (deltas serialized as decimal strings).

Usage Examples

Apply a delta to balances

use indexmap::IndexMap;
use ank_accounting::{Balances, BalancesDelta, TokenId};

let mut bal = Balances(IndexMap::new());
let usdc = TokenId(1);
bal.set(usdc, 1_000_000_000_000_000_000u128); // 1e18

let mut d = IndexMap::new();
d.insert(usdc, -500_000_000_000_000_000i128); // -0.5e18
let delta = BalancesDelta(d);

bal.apply_delta(&delta).unwrap();
assert_eq!(bal.get(usdc), 500_000_000_000_000_000u128);

Managing user balances

use indexmap::IndexMap;
use ank_accounting::{Balances, TokenId};

let mut b = Balances(IndexMap::new());
let eth = TokenId(0);

// Initially returns 0
assert_eq!(b.get(eth), 0);

// Set balance
b.set(eth, 42);
assert_eq!(b.get(eth), 42);

Conventions

  • Amounts are represented as 1e18-scaled integers unless otherwise stated
  • Applying a negative delta that exceeds the current balance saturates at zero (no panic)
  • All operations use saturating arithmetic to prevent overflows and underflows

Build docs developers (and LLMs) love