Evolution SDK
Architecture

Unfrack Optimization

UTxO structure optimization through strategic bundling and subdivision

Abstract

Cardano UTxOs carry both ADA and native assets (tokens, NFTs). Poorly structured UTxOs create wallet fragmentation—many small UTxOs that increase transaction size and fees. The unfrack optimization addresses this by strategically bundling tokens and subdividing ADA during change creation, producing an optimal UTxO structure that minimizes future transaction costs while maintaining protocol validity constraints.

Purpose and Scope

Purpose: Transform arbitrary change assets into an optimized set of UTxOs that reduce future transaction costs and improve wallet usability.

Scope:

  • Applies during change creation phase when leftover assets exist
  • Operates on ADA-only scenarios, token-only scenarios, or mixed scenarios
  • Respects protocol constraints (minUTxO requirements for each output)
  • Named in respect to the Unfrack.It principles

Out of Scope:

  • Input selection strategies (handled by coin selection phase)
  • Fee optimization (handled by fee calculation phase)
  • Multi-transaction wallet defragmentation

Design Philosophy

Unoptimized change outputs create technical debt. A wallet with 50 small UTxOs requires larger transactions (more inputs) to make payments, increasing fees. A wallet with all assets on one UTxO forces users to "break" that UTxO for every transaction, creating change recursively.

The solution operates on first principles: separate concerns (tokens from ADA), group related assets (same-policy tokens), and create spending flexibility (subdivided ADA). When change is created, the system checks if optimization is affordable—if the leftover exceeds minimum requirements for multiple outputs, it distributes intelligently. If not, it consolidates into a single valid output.

This preserves three guarantees: protocol validity (all outputs meet minUTxO), asset conservation (no assets lost), and spending efficiency (future transactions use fewer inputs).

Token Bundling Strategy

Tokens are distributed into bundles based on policy ID and configurability:

Key Behaviors:

  • Tokens are grouped by policy ID to avoid unnecessary asset mixing
  • Each bundle respects bundleSize configuration (default: 10 tokens per UTxO)
  • MinUTxO is calculated per bundle using CBOR-accurate size estimation
  • Same-policy tokens stay together unless count exceeds bundle size

ADA Distribution Strategy

After token bundles are created with their minimum ADA requirements, remaining ADA follows a decision flow:

Two Core Strategies:

SPREAD: Distributes remaining ADA evenly across token bundles. Used when:

  • Remaining ADA is below subdivideThreshold (default: 100 ADA), OR
  • Remaining ADA cannot afford a separate valid output (< minUTxO)

SUBDIVIDE: Creates multiple ADA-only outputs using percentage-based distribution. Used when:

  • Remaining ADA >= subdivideThreshold, AND
  • Remaining ADA >= minUTxO for standalone output, AND
  • Smallest percentage-based amount >= minUTxO

ADA-Only Scenario

When no tokens exist in change, the decision flow simplifies:

This creates spending flexibility: users can make small payments without breaking large UTxOs. Default percentages (50%, 15%, 10%, 10%, 5%, 5%, 5%) provide a logarithmic distribution suitable for typical transaction patterns.

Configuration Options

The unfrack behavior adapts through tunable parameters that balance UTxO count against spending flexibility:

Subdivision Threshold: Controls when ADA gets split into multiple outputs. Default is 100 ADA—below this, ADA spreads across token bundles; above this, ADA creates separate outputs. Lower thresholds increase subdivision frequency (more UTxOs, greater flexibility). Higher thresholds reduce output count (fewer UTxOs, less flexibility).

Subdivision Percentages: Defines the distribution pattern for ADA-only outputs. Default pattern (50%, 15%, 10%, 10%, 5%, 5%, 5%) creates a logarithmic spread suitable for typical spending patterns—one large output for major transactions, several medium outputs for regular use, and multiple small outputs for micro-transactions.

Bundle Size: Limits tokens per UTxO. Default is 10 tokens per bundle. Smaller sizes create more bundles (more outputs, easier to spend individual tokens). Larger sizes consolidate tokens (fewer outputs, but spending one token requires moving all bundled tokens).

Policy Isolation: Controls whether tokens of the same policy stay together or separate. Isolation creates one UTxO per fungible policy (more outputs, cleaner separation). Grouping bundles mixed policies up to bundle size (fewer outputs, more mixing).

NFT Grouping: Determines whether NFTs cluster by policy or mix freely. Policy-based grouping keeps same-collection NFTs together (logical organization). Free mixing prioritizes bundle size limits (arbitrary grouping).

These parameters trade off UTxO count (affects wallet size, scanning time) against spending efficiency (affects transaction size, input requirements). The defaults favor spending efficiency—most users benefit more from flexible UTxOs than from minimizing wallet size.

Affordability Guarantees

All unfrack operations maintain protocol validity through affordability checks:

  1. Pre-Flight Check: Change creation phase validates that leftover >= minUTxO for single output before attempting unfrack
  2. Per-Bundle MinUTxO: Each token bundle calculates its minimum using CBOR-accurate size estimation
  3. Subdivision Validation: Before subdividing ADA, verifies smallest percentage-based amount >= minUTxO
  4. Fallback Path: If unfrack is unaffordable, falls back to single consolidated change output (guaranteed valid by pre-flight check)

This ensures unfrack never creates invalid outputs. If optimization is unaffordable, the system safely degrades to simple change creation.

Integration Points

Unfrack integrates with the transaction builder at the change creation phase:

Change Creation Phase: When BuildOptions.unfrack is enabled and change outputs need to be created, the builder calls createUnfrackedChangeOutputs(). If unfrack succeeds, multiple optimized outputs are stored. If unfrack is unaffordable (insufficient ADA for multiple valid outputs), it returns a single change output.

Fee Calculation Phase: After unfrack creates outputs, fees are recalculated based on the new transaction size. Multiple outputs increase size slightly, but this is intentional—the cost is paid once during change creation, avoiding higher costs across many future transactions.

Build Options: Users enable unfrack by providing unfrack configuration in BuildOptions. If omitted, change creation uses simple single-output strategy.