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

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.evo.market/technical/iasset-lp-rewards-distribution.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
