> For the complete documentation index, see [llms.txt](https://docs.evo.market/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.evo.market/technical/iasset-lp-rewards-distribution.md).

# iAsset LP Rewards Distribution

### Overview

The **iAsset LP Rewards Manager** implements a **pro-rata distribution mechanism** for allocating iAsset rewards to liquidity providers based on their actual iAsset token holdings within their positions.

***

{% hint style="warning" %}
iAsset LP Rewards Distribution is currently in development and available **only on the Supra Testnet.**
{% endhint %}

### Distribution Mechanism

#### Core Principle: Pro-Rata by Token Amount

Unlike traditional LP rewards that distribute based on liquidity share, iAsset rewards are distributed **proportionally to the actual amount of iAsset tokens** held in each position.

**Key Formula:**

```rust
reward_per_token = new_rewards × Q64 / total_iasset_amount
user_rewards = user_iasset_amount × (current_rate - last_claimed_rate) / Q64
```

**Where:**

* `new_rewards`: Total new iAsset rewards accumulated since the last harvest
* `total_iasset_amount`: Sum of all iAsset tokens across all LP positions
* `user_iasset_amount`: Actual iAsset token amount in a specific position
* `Q64`: Fixed-point precision factor (`2^64`) to prevent rounding errors

***

#### Why Token Amount, Not Liquidity?

In concentrated liquidity pools, the same liquidity value can represent vastly different token amounts depending on the price range:

* **Position A:** 1000 liquidity at price range \[$1–$2] → holds \~500 token0 + 500 token1
* **Position B:** 1000 liquidity at price range \[$0.01–$0.02] → holds \~50,000 token0 + 50 token1

If rewards were distributed purely by liquidity, both would receive the same rewards — even though Position B holds 100× more token0.\
By distributing based on actual token amounts, the system ensures **fair, proportional rewards**.

***

### How It Works

#### 1. Harvest Phase

The `harvest_rewards()` function periodically checks for new iAsset rewards:

```rust
// Calculate new rewards since last harvest
new_rewards = current_balance - last_harvested_balance

// Only distribute if there are positions with this iAsset
if (total_iasset_0_amount > 0 && new_rewards > 0) {
    // Calculate reward rate per token
    reward_per_token = (new_rewards × Q64) / total_iasset_0_amount

    // Accumulate global rate
    reward_growth_global_0 += reward_per_token

    // Update checkpoint
    last_harvested_balance_0 = current_balance
}
```

**Key Points:**

* Rewards are harvested by comparing current balance vs. last known balance
* Distribution only occurs if positions hold the iAsset (`total_iasset_amount > 0`)
* The global rate accumulates over time, tracking total rewards per token
* Works independently for `token0` and `token1`

***

#### 2. Position Tracking

When users add or remove liquidity, the system tracks their iAsset token amounts.

**On Liquidity Added:**

```rust
// Update position's iAsset amount
position.iasset_amount_0 += amount_0
pool.total_iasset_0_amount += amount_0

// Checkpoint: prevent new deposit from being counted as rewards
last_harvested_balance_0 = current_balance
```

**On Liquidity Removed:**

* Harvest any new rewards first
* Update position rewards to capture pending amounts
* Update tracked iAsset token amounts accordingly

***

#### 3. Reward Calculation

Rewards for a position are calculated using the accumulated rate pattern:

```rust
// Calculate reward growth inside position's price range
reward_growth_inside = calculate_growth_in_range(tick_lower, tick_upper, current_tick)

// Calculate pending rewards based on iAsset amount held
delta_reward = (reward_growth_inside - last_claimed_rate) × iasset_amount / Q64

// Accumulate to amount owed
amount_owed += delta_reward
```

***

#### 4. Claiming Rewards

Users can claim accumulated rewards via `claim_rewards()`:

1. Harvest any new rewards from the pool
2. Update the position to calculate pending amounts
3. Transfer owed rewards to the user
4. Reset `amount_owed` and update claim timestamp

***

### Distribution Properties

#### Fairness Guarantees

* **Pro-rata by token amount:**\
  Users holding 10% of total iAsset tokens receive 10% of rewards — independent of liquidity share or price range.
* **No double-counting:**\
  Checkpointing ensures new deposits aren’t mistakenly rewarded.
* **Time-independent:**\
  Two positions holding equal iAsset amounts for equal time periods earn the same rewards, regardless of entry/exit timing.
* **Price-range independent:**\
  Rewards depend only on token holdings, not on which price range liquidity is provided.

***

#### Active vs. Inactive Range

Unlike fee rewards, which accrue only when positions are in the **active price range**, iAsset rewards distribute **globally** to all positions holding iAsset tokens:

* A position can be completely out of range (no active liquidity)
* As long as it holds iAsset tokens, it earns rewards
* This is intentional — iAsset rewards are **governance/protocol incentives**, not trading fees

***

### Example Scenario

**Setup:**

* Pool has two positions with `token0` as iAsset
* Position A: 1,000 iAsset
* Position B: 4,000 iAsset
* Total: 5,000 iAsset

**Reward Distribution:**

1. Pool receives 500 new iAsset rewards
2. `reward_per_token = 500 × 2^64 / 5,000`
3. Position A: `1,000 × reward_per_token / 2^64 = 100` rewards (20%)
4. Position B: `4,000 × reward_per_token / 2^64 = 400` rewards (80%)

✅ **Result:** Perfectly pro-rata distribution based on token holdings.

***

### Technical Details

#### Precision & Overflow Prevention

* Uses **Q64.64 fixed-point arithmetic** (`2^64` precision)
* All intermediate calculations use `u256` to prevent overflow
* Final results are safely downcast to `u64` for token transfers

***

#### Tick-Based Growth Tracking

Similar to Uniswap v3, the system tracks **reward growth per tick boundary**:

* `tick_rewards_0` and `tick_rewards_1` map each tick to its `reward_growth_outside`
* `reward_growth_inside` is derived for each position based on its tick range
* Enables **precise accounting** for overlapping or partially active ranges

***

#### State Variables

**Global (per pool):**

* `reward_growth_global_0/1`: Accumulated reward rate per token
* `total_iasset_0/1_amount`: Total iAsset tokens held in positions
* `last_harvested_balance_0/1`: Checkpoint for detecting new rewards

**Per Position:**

* `iasset_amount_0/1`: Actual iAsset tokens in this position
* `reward_growth_inside_last_0/1`: Last claimed rate
* `amount_owed_0/1`: Pending unclaimed rewards

***

### Integration Points

#### When to Harvest

The system automatically harvests in these scenarios:

1. **On liquidity removal:** Ensures latest rewards are distributed before changes
2. **On claim:** Ensures user receives all accumulated rewards
3. **Periodically:** Can be called by anyone to update global state

***

### Summary

The **iAsset LP Rewards Distribution** system provides:

1. Fair **pro-rata distribution** based on actual iAsset token holdings
2. Efficient global state tracking using accumulated rates
3. Precise per-position accounting via tick-based growth calculations
4. Protection against double-counting, overflow, and zero-division errors
5. Full compatibility with existing concentrated liquidity mechanics

**Result:**\
All liquidity providers receive rewards proportional to their true iAsset contributions — **independent of price ranges, liquidity concentration, or activity status.**

***
