# Tick

### Core Data Structures

**TickManager**

The main controller that organizes all ticks for a pool:

```rust
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:

```rust
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

```rust
public(friend) fun new(tick_spacing: u32, seed: u64, ctx: &mut TxContext) : TickManager
```

Creates a new tick manager with:

* Specified tick spacing
* Empty SkipList with randomized structure
* 16 levels maximum for optimal performance

#### Liquidity Management

**Adding Liquidity**

```rust
public(friend) fun increase_liquidity(
    tick_manager: &mut TickManager,
    current_tick: I32,
    tick_lower: I32,
    tick_upper: I32,
    amount: u128,
    fee_growth_global_a: u128,
    fee_growth_global_b: u128,
    points_growth_global: u128,
    rewards_growth_global: vector<u128>
)
```

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**

```rust
public(friend) fun decrease_liquidity(
    tick_manager: &mut TickManager,
    current_tick: I32,
    tick_lower: I32,
    tick_upper: I32,
    amount: u128,
    fee_growth_global_a: u128,
    fee_growth_global_b: u128,
    points_growth_global: u128,
    rewards_growth_global: vector<u128>
)
```

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**

```rust
public(friend) fun cross_by_swap(
    tick_manager: &mut TickManager,
    tick_idx: I32,
    a2b: bool,
    liquidity: u128,
    fee_growth_global_a: u128,
    fee_growth_global_b: u128,
    points_growth_global: u128,
    rewards_growth_global: vector<u128>
) : u128
```

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**

```rust
public fun first_score_for_swap(
    tick_manager: &TickManager,
    tick_idx: I32,
    a2b: bool
) : OptionU64
```

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

```rust
public fun borrow_tick_for_swap(
    tick_manager: &TickManager,
    node_id: u64,
    a2b: bool
) : (&Tick, OptionU64)
```

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

#### Range Calculations

**Fee Growth in Range**

```rust
public fun get_fee_in_range(
    current_tick: I32,
    fee_growth_global_a: u128,
    fee_growth_global_b: u128,
    tick_lower_opt: Option<Tick>,
    tick_upper_opt: Option<Tick>
) : (u128, u128)
```

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

```rust
fee_inside = fee_global - fee_below - fee_above
```

Where:

* `fee_below`: Fee growth below the lower tick
* `fee_above`: Fee growth above the upper tick

**Points Growth in Range**

```rust
public fun get_points_in_range(
    current_tick: I32,
    points_growth_global: u128,
    tick_lower_opt: Option<Tick>,
    tick_upper_opt: Option<Tick>
) : u128
```

Similar calculation for points (used in reward calculations).

**Rewards Growth in Range**

```rust
public fun get_rewards_in_range(
    current_tick: I32,
    rewards_growth_global: vector<u128>,
    tick_lower_opt: Option<Tick>,
    tick_upper_opt: Option<Tick>
) : vector<u128>
```

Calculates reward growth for multiple reward tokens within a range.

### Advanced Features

#### Tick Discovery and Querying

**Pagination Support**

```rust
public fun fetch_ticks(
    tick_manager: &TickManager,
    start: vector<u32>,
    limit: u64
) : vector<Tick>
```

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**

```rust
public fun borrow_tick(tick_manager: &TickManager, tick_idx: I32) : &Tick
public fun try_borrow_tick(tick_manager: &TickManager, tick_idx: I32) : Option<Tick>
```

* `borrow_tick`: Direct access (aborts if not found)
* `try_borrow_tick`: Safe access returning Option

#### Data Access Functions

**Tick Properties**

```rust
public fun index(tick: &Tick) : I32
public fun sqrt_price(tick: &Tick) : u128
public fun liquidity_gross(tick: &Tick) : u128
public fun liquidity_net(tick: &Tick) : I128
public fun fee_growth_outside(tick: &Tick) : (u128, u128)
public fun points_growth_outside(tick: &Tick) : u128
public fun rewards_growth_outside(tick: &Tick) : &vector<u128>
```

**Manager Properties**

```rust
public fun tick_spacing(tick_manager: &TickManager) : u32
public fun tick_count(tick_manager: &TickManager) : u64
```

**Reward Helpers**

```rust
public fun get_reward_growth_outside(tick: &Tick, index: u64) : u128
```

Safely accesses reward growth for a specific reward token index.

### Internal Implementation

#### Tick Scoring System

```rust
fun tick_score(tick_idx: I32) : u64
```

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

```rust
fun default(tick_idx: I32) : Tick
```

Creates new tick with:

* Calculated sqrt\_price from tick\_math
* Zero liquidity values
* Zero growth tracking values
* Empty rewards vector

#### Liquidity Update Logic

```rust
fun update_by_liquidity(
    tick: &mut Tick,
    current_tick: I32,
    amount: u128,
    is_new: bool,
    is_increase: bool,
    is_upper: bool,
    fee_growth_global_a: u128,
    fee_growth_global_b: u128,
    points_growth_global: u128,
    rewards_growth_global: vector<u128>
) : u128
```

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:

```rust
price = 1.0001^tick_index
sqrt_price = sqrt(price) = 1.0001^(tick_index/2)
```

#### Liquidity Net Calculation

When crossing tick from left to right:

```rust
new_liquidity = current_liquidity + tick.liquidity_net
```

For reverse direction (right to left):

```
new_liquidity = current_liquidity - tick.liquidity_net
```

#### Growth Outside Pattern

Fee growth inside a range \[tickLower, tickUpper]:

```rust
fee_inside = fee_global - fee_below - fee_above

where:
fee_below = (current_tick >= tickLower) ? tickLower.fee_outside : (fee_global - tickLower.fee_outside)
fee_above = (current_tick < tickUpper) ? tickUpper.fee_outside : (fee_global - tickUpper.fee_outside)
```

### 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
