Skip to main content

๐ŸŠ Pools

Pools are the third major architecture layer after Digests and Indexes.

If Digest is:

single economic state anchor

and Index is:

immutable grouped digest structure

then Pool is:

manager-controlled dynamic commitment allocation

Pools allow many users to commit into one shared structure, while a designated manager controls how those commitments are distributed across multiple digests.

This enables:

  • ๐Ÿ› delegated staking systems
  • ๐Ÿ’ฐ managed vaults
  • ๐Ÿ“ˆ operator-controlled portfolios
  • ๐Ÿงบ validator allocation services
  • โš™ protocol-managed financial strategies

Unlike indexes:

Index = structure

Pool = active management

Pools are built for dynamic allocation.


๐ŸŽฏ What a Pool Really Isโ€‹

A Pool is not:

  • direct ownership
  • custodial wallet access
  • manager-owned funds

A Pool is:

a managed indirect digest

where users commit to the pool digest itself, and the pool manager redistributes those commitments across multiple underlying digests.

Users -> Pool Digest -> Slot Digests -> Real economic balances
  • The manager controls allocation.
  • The manager does not own funds.
  • Allocation privilege is not ownership.

๐Ÿงฉ The CommitPool Traitโ€‹

This trait defines all pool operations.

impl CommitPool<Proprietor<T>> for pallet_commitment::Pallet<T, I> { ... }

It extends commitment behavior from:

immutable grouped commitments

to

dynamically managed grouped commitments

This is the architecture boundary between indexes and pools.

Key Methodsโ€‹

MethodPurpose
get_pool_value(reason, pool)Returns the live aggregated value of the full pool across all slots
gen_pool_digest(manager, reason, index, commission)Generates a unique digest for the pool from manager, index, and commission
set_pool(who, reason, pool, index, commission)Creates a new managed pool from an existing index's structure
set_slot_shares(who, reason, pool, slot, shares)Rebalances slot allocation through full release and re-deposit
set_pool_manager(reason, pool, manager)Transfers pool management priviledges of an existing active pool
get_commission(reason, pool)Returns the immutable manager commission of the pool
reap_pool(reason, pool)Safely removes an empty pool with no active commitments

๐Ÿท๏ธ Core Typesโ€‹

Pool Digestโ€‹

type PoolDigest = Digest

The digest users commit to.

This is the top-level managed commitment target.

Slot Digestโ€‹

type SlotDigest = Digest

Each pool contains slots.

Each slot behaves like a managed grouped position copied from index structure.

Pool Managerโ€‹

type Proprietor = AccountId

The manager is simply a proprietor account stored separately.

The manager can:

  • redistribute commitments
  • rebalance allocation
  • adjust strategy
  • take optional commissions during resolution

The manager cannot:

  • directly spend user funds
  • withdraw user commitments
  • bypass resolution rules
  • mutate already-announced commission

Allocation privilege is not ownership.


๐Ÿ—‚๏ธ Storage Mapsโ€‹

PoolMapโ€‹

(Reason, PoolDigest) -> PoolInfo

Stores the full pool structure:

  • slot structure (share-based allocation)
  • current managed balance (top-level pool-balance)
  • commission configuration
  • aggregate pool state

This defines what the pool is

It stores topology, not user ownership.

User ownership remains in CommitMap still.

PoolManagerโ€‹

(Reason, PoolDigest) -> Proprietor

Stores the designated manager of the pool.

This manager controls:

  • slot allocation
  • redistribution strategy
  • operational management

but never direct ownership of user funds.

CommitMapโ€‹

(Proprietor, Reason) -> CommitInfo

Still exists exactly like direct commitments and indexes.

It points to the Pool Digest.

This preserves the invariant:

one proprietor -> one commitment per reason

even inside managed pool systems.


๐Ÿ›ก Pool Invariantsโ€‹

Pools preserve strict invariants:

  • ๐Ÿงฑ manager controls allocation only
  • ๐Ÿšซ manager never owns funds
  • ๐Ÿ’ธ commissions remain bounded
  • ๐Ÿงพ receipts remain immutable
  • โšก lazy resolution stays deterministic
  • ๐Ÿงน reap only when fully empty

Pools add management without breaking ownership safety.

๐Ÿงฑ Pools Are Created From Indexesโ€‹

Pools are initially created from existing indexes.

They do not own the index.

They only copy the index structure.

This works because both indexes and pools use the same foundation:

share-based grouped allocation

An index already provides:

  • bounded entries
  • weighted shares
  • deterministic structure

So during pool creation:

Pool
-> copies Index structure
-> creates Pool Slots
-> manages allocation independently

After creation:

the pool is fully independent
  • Later changes to the index do not affect the pool.
  • Later pool rebalancing does not affect the index.

This is the key distinction.

Index = immutable template

Pool = managed runtime structure

Indexes provide safe initial structure.

Pools take that structure and continue independently with manager-controlled allocation.

โšก How Pools Actually Workโ€‹

This is the most important part of pool architecture.

A pool behaves like:

a balance on top of balances

Just like a digest holds a lazy balance and gives receipts to proprietors,

a pool also holds its own top-level lazy balance and gives pool-level receipts to users.

Proprietor
-> commits to Pool Digest
-> receives Pool Receipt

But the real economic value is still distributed underneath like the pool commits as a proprietor into:

Slot Digests
-> Direct Digests

This means:

Pool = top-level managed balance

Slots = actual distributed execution

The pool itself acts like a pseudo-proprietor.

It holds one collective balance over many underlying balances.

๐Ÿ”„ Why Pool Operations Require Full Releaseโ€‹

Because the pool maintains its own top-level balance,

every structural operation must preserve correctness between pool balance and slot balances (digests).

That means operations like:

  • deposit
  • withdrawal
  • manager rebalancing
  • slot redistribution
  • commission updates

cannot safely mutate slots partially.

Instead, the system always performs:

-> full pool release
-> withdraw all slot digests
-> recover total pool value
-> rebuild allocation
-> re-deposit into slot digests

This guarantees:

  • deterministic accounting
  • correct receipt preservation
  • no stale slot state
  • safe manager-controlled redistribution

Pools always rebalance from the full top-level balance.

Never from partial mutation.

Its like pool (as a pseudo-proprietor) resolving its commitment and redo again placing commitment for every pool mutation operation.

๐Ÿงพ Pool Receiptsโ€‹

Users never receive receipts from slot digests directly.

They receive:

one pool-level receipt

for their commitment to the pool.

Internally, the pool manages many slot-level commit receipts that represent how value is distributed underneath.

This keeps ownership simple:

user owns pool commitment, pool manages slot commitments

without exposing internal complexity.

๐ŸŽ› Manager Rebalancingโ€‹

When the manager changes allocation:

it does not directly mutate balances inside slots.

Instead:

-> withdraw all slots
-> recover pool balance
-> apply new strategy
-> deposit again across slots

This is why pool management stays safe where allocation changes are full re-compositions, not unsafe in-place mutations.

That is the fundamental difference from indexes. Indexes are immutable.

Pools are mutable through full controlled re-resolution.

โšก Lazy Resolution of Poolsโ€‹

Exactly like indexes:

receipts are immutable

but

underlying digests continue changing

Example:

Alice commits to Pool (A, B)

Manager reallocates pool structure

Validator A gains rewards
Validator B gets slashed

When Alice resolves:

-> withdraw through pool
-> Pool fully releases
-> Determine Alice's Pool Portion
-> aggregate final result
-> return one final amount

Users never manually track reallocation.

Resolution happens lazily.

Remember, slots don't track a proprietor's individual deposits. They simply represent their share of your current pool value.

๐Ÿ’ธ Pool Manager Commissionโ€‹

Pools support optional manager commissions.

This commission is the manager's reward for providing allocation and operational management.

It is defined as:

percentage-based commission

and is only collected during commit resolution (withdrawal), not during deposit or rebalancing.

This keeps pool accounting predictable and prevents hidden balance deductions during active commitment periods.

๐Ÿงฑ Commission Is Immutableโ€‹

A pool's commission cannot be modified after creation.

It is part of the pool's economic identity.

This guarantees:

  • predictable user expectations
  • stable receipt resolution
  • deterministic final settlement
  • safe historical accounting

Users must always know the exact commission rules attached to the pool they entered.

๐Ÿ”„ Changing Commission Creates a New Poolโ€‹

If commission must change, the existing pool is never mutated

Instead:

-> create new empty pool
-> assign new commission
-> new commitments enter new pool

The old pool continues serving existing commitments under its original commission rules until fully resolved and reaped.

This preserves correctness for all historical receipts.

Exactly like index immutability:

index change -> new index

commission change -> new pool

No retroactive economic mutation is allowed.

๐Ÿงน Reaping a Poolโ€‹

A pool can only be removed when:

  • no active commitments
  • no remaining managed funds

Only then can it be safely reaped.

This prevents destruction of active delegated economic state.


๐Ÿ“Œ In One Sentenceโ€‹

A Pool is a manager-controlled commitment layer built on top of indexes, allowing delegated allocation without custodial ownership.

Digest = state

Index = grouped structure

Pool = managed allocation

๐Ÿš€ Next Stepโ€‹

Now we move into how balances are actually settled through a plugin based lazy receipts, minting, reaping, and imbalance resolution.

๐Ÿ‘‰ Architecture -> Balance Engine