For the complete documentation index, see llms.txt. This page is also available as Markdown.

Tick

Manages the discrete price points and liquidity distribution across the price curve.

Core Data Structures

TickManager

The main controller that organizes all ticks for a pool:

struct TickManager {
    tick_spacing: u32,           // Spacing between valid ticks
    ticks: SkipList<Tick>       // Ordered collection of ticks
}

Tick

Individual tick containing all relevant price point data:

struct Tick {
    index: I32,                          // Tick index (price level)
    sqrt_price: u128,                    // Square root price at this tick
    liquidity_net: I128,                 // Net liquidity change when crossing
    liquidity_gross: u128,               // Total liquidity at this tick
    fee_growth_outside_a: u128,          // Fee growth outside for token A
    fee_growth_outside_b: u128,          // Fee growth outside for token B
    points_growth_outside: u128,         // Points growth outside
    rewards_growth_outside: vector<u128> // Reward growth outside (per token)
}

Key Properties

Liquidity Net vs Gross

  • liquidity_net: Signed change in active liquidity when crossing this tick

    • Positive when tick is the lower bound of positions

    • Negative when tick is the upper bound of positions

  • liquidity_gross: Total amount of liquidity referencing this tick

    • Always positive

    • Used to determine if tick can be removed

Growth Outside Pattern

The "growth outside" pattern enables efficient fee and reward calculations:

  • Tracks accumulated growth outside the current active range

  • Allows O(1) calculation of growth within any range

  • Automatically updated when ticks are crossed during swaps

Core Functionality

Initialization

Creates a new tick manager with:

  • Specified tick spacing

  • Empty SkipList with randomized structure

  • 16 levels maximum for optimal performance

Liquidity Management

Adding Liquidity

Process:

  1. Tick Creation: Creates ticks if they don't exist

  2. Lower Tick Update: Increases liquidity_net (positive delta)

  3. Upper Tick Update: Decreases liquidity_net (negative delta)

  4. Growth Initialization: Sets appropriate "outside" growth values

Removing Liquidity

Process:

  1. Validation: Ensures ticks exist and have sufficient liquidity

  2. Liquidity Reduction: Decreases gross liquidity at both ticks

  3. Net Adjustment: Adjusts net liquidity appropriately

  4. Cleanup: Removes ticks if no liquidity remains

Swap Operations

Tick Crossing

When a swap crosses a tick:

  1. Liquidity Update: Applies liquidity_net to active liquidity

  2. Direction Handling: Negates delta for reverse direction (a2b)

  3. Growth Flipping: Updates "outside" growth values using wrapping subtraction

  4. Safety Checks: Validates liquidity doesn't overflow or underflow

Swap Navigation

Finds the next tick to process during swaps:

  • a2b (true): Finds previous tick (lower price)

  • b2a (false): Finds next tick (higher price)

  • Handles edge cases at minimum and maximum ticks

Returns current tick data and next tick ID for efficient swap iteration.

Range Calculations

Fee Growth in Range

Calculates accumulated fees within a position's range using the formula:

Where:

  • fee_below: Fee growth below the lower tick

  • fee_above: Fee growth above the upper tick

Points Growth in Range

Similar calculation for points (used in reward calculations).

Rewards Growth in Range

Calculates reward growth for multiple reward tokens within a range.

Advanced Features

Tick Discovery and Querying

Pagination Support

Efficiently retrieves ticks with pagination:

  • start: Optional starting tick index

  • limit: Maximum number of ticks to return

  • Returns ordered list for UI display

Tick Lookup

  • borrow_tick: Direct access (aborts if not found)

  • try_borrow_tick: Safe access returning Option

Data Access Functions

Tick Properties

Manager Properties

Reward Helpers

Safely accesses reward growth for a specific reward token index.

Internal Implementation

Tick Scoring System

Converts tick indices to SkipList scores:

  • Handles negative tick indices

  • Ensures proper ordering in SkipList

  • Maps to range [0, tick_bound * 2]

Default Tick Creation

Creates new tick with:

  • Calculated sqrt_price from tick_math

  • Zero liquidity values

  • Zero growth tracking values

  • Empty rewards vector

Liquidity Update Logic

Core logic for updating tick state:

  1. Gross Liquidity: Add/subtract amount based on is_increase

  2. Net Liquidity: Adjust based on is_upper flag

  3. Growth Initialization: Set "outside" values for new ticks based on current position

  4. Overflow Protection: Check for arithmetic overflows

  5. Return Remaining: Return remaining gross liquidity

Growth Initialization Logic

For new ticks:

  • Below current tick: Initialize outside growth to 0 (all growth is "above")

  • Above current tick: Initialize outside growth to global values (all growth is "below")

This ensures proper fee/reward calculations when the tick becomes active.

Error Codes

  • Error 0: Arithmetic overflow in liquidity calculations

  • Error 1: Insufficient liquidity for operation

  • Error 2: Invalid tick score (outside valid range)

  • Error 3: Tick not found when expected to exist

Mathematical Concepts

Price Calculation

Each tick represents a specific price:

Liquidity Net Calculation

When crossing tick from left to right:

For reverse direction (right to left):

Growth Outside Pattern

Fee growth inside a range [tickLower, tickUpper]:

Performance Characteristics

Time Complexity

  • Tick lookup: O(log n)

  • Tick insertion/deletion: O(log n)

  • Range queries: O(log n + k) where k is result size

  • Crossing tick: O(1)

  • Fee/reward calculation: O(1)

Space Complexity

  • Memory per tick: ~200 bytes + rewards vector

  • SkipList overhead: ~16 pointers per tick

  • Total for n ticks: O(n)

Gas Efficiency

  • Efficient sparse storage (only initialized ticks consume gas)

  • O(1) tick crossing operations

  • Batch operations for multiple tick updates

  • Optimized wrapping arithmetic for growth calculations

Best Practices

  1. Tick Spacing: Choose spacing based on gas costs vs. precision needs

  2. Batch Operations: Group multiple liquidity operations when possible

  3. Error Handling: Always check for tick existence before operations

  4. Memory Management: Clean up empty ticks to reduce storage costs

  5. Precision: Use appropriate decimal precision for price calculations

Security Considerations

  1. Overflow Protection: All arithmetic operations include overflow checks

  2. Tick Bounds: Validate tick indices are within valid range

  3. Liquidity Validation: Ensure sufficient liquidity before decreasing

  4. Growth Calculation: Use wrapping arithmetic to handle edge cases

  5. Access Control: Restrict dangerous operations to friend modules only

Last updated