# Lending Core

As a developer, your primary interactions with the NAVI Protocol will take place through the functions within the **`lending_core::incentive_v3`** module. This module serves as the entry point for all write transactions, including deposits, withdrawals, borrowing, repayment, liquidations, and reward claims

## Entry Functions

### entry\_deposit

{% hint style="info" %}
This function allows a user to deposit a specified amount of a given coin type into a lending pool. The deposit amount is added to the pool's balance, and a deposit event is emitted.
{% endhint %}

```rust
public entry fun entry_deposit<CoinType>(
    clock: &Clock,
    storage: &mut Storage,
    pool: &mut Pool<CoinType>,
    asset: u8,
    deposit_coin: Coin<CoinType>,
    amount: u64,
    incentive_v2: &mut IncentiveV2,
    incentive_v3: &mut Incentive,
    ctx: &mut TxContext
) {}
```

### entry\_withdraw\_v2

{% hint style="info" %}
This function allows a user to withdraw a specified amount from a lending pool. The withdrawal amount is deducted from the pool's balance, and a withdrawal event is emitted.
{% endhint %}

```rust
public entry fun entry_withdraw_v2<CoinType>(
    clock: &Clock,
    oracle: &PriceOracle,
    storage: &mut Storage,
    pool: &mut Pool<CoinType>,
    asset: u8,
    amount: u64,
    incentive_v2: &mut IncentiveV2,
    incentive_v3: &mut Incentive,
    system_state: &mut SuiSystemState,
    ctx: &mut TxContext
) {}
```

### entry\_borrow\_v2

{% hint style="info" %}
This function allows a user to borrow a specified amount from a lending pool. The borrowed amount is deducted from the pool's balance, and a borrow event is emitted.
{% endhint %}

```rust
public entry fun entry_borrow_v2<CoinType>(
    clock: &Clock,
    oracle: &PriceOracle,
    storage: &mut Storage,
    pool: &mut Pool<CoinType>,
    asset: u8,
    amount: u64,
    incentive_v2: &mut IncentiveV2,
    incentive_v3: &mut Incentive,
    system_state: &mut SuiSystemState,
    ctx: &mut TxContext
) {}
```

### entry\_repay

{% hint style="info" %}
This function allows a user to repay a specified loan amount. The repayment amount is added to the pool's balance, and a repay event is emitted.
{% endhint %}

```rust
public entry fun entry_repay<CoinType>(
    clock: &Clock,
    oracle: &PriceOracle,
    storage: &mut Storage,
    pool: &mut Pool<CoinType>,
    asset: u8,
    repay_coin: Coin<CoinType>,
    amount: u64,
    incentive_v2: &mut IncentiveV2,
    incentive_v3: &mut Incentive,
    ctx: &mut TxContext
) {}
```

### claim\_reward\_entry

{% hint style="info" %}
This function allows users to claim rewards in a specified reward coin. Rewards are distributed from the bonus pool and a claim reward event is emitted.
{% endhint %}

<pre><code><strong>public entry fun claim_reward_entry&#x3C;RewardCoinType>(
</strong>    clock: &#x26;Clock, 
    incentive: &#x26;mut Incentive,
    storage: &#x26;mut Storage, 
    reward_fund: &#x26;mut RewardFund&#x3C;RewardCoinType>,
    coin_types: vector&#x3C;String>,
    rule_ids: vector&#x3C;address>,
    ctx: &#x26;mut TxContext
) {}
</code></pre>

### entry\_liquidation\_v2

{% hint style="info" %}
This function is used to liquidate a loan when a borrower's collateral is insufficient to cover their debt. The liquidation process repays the debt, returning any excess amount to the sender. A liquidation call event is emitted.
{% endhint %}

```rust
public entry fun entry_liquidation_v2<DebtCoinType, CollateralCoinType>(
    clock: &Clock,
    oracle: &PriceOracle,
    storage: &mut Storage,
    debt_asset: u8,
    debt_pool: &mut Pool<DebtCoinType>,
    debt_coin: Coin<DebtCoinType>,
    collateral_asset: u8,
    collateral_pool: &mut Pool<CollateralCoinType>,
    liquidate_user: address,
    liquidate_amount: u64,
    incentive_v2: &mut IncentiveV2,
    incentive_v3: &mut Incentive,
    system_state: &mut SuiSystemState, 
    ctx: &mut TxContext
) {}
```

## Non-entry Functions

### deposit\_with\_account\_cap

{% hint style="info" %}
This function is similar to a standard deposit but includes an account cap limitation. The deposit amount is added to the pool's balance, and a deposit event is emitted.
{% endhint %}

<pre class="language-rust"><code class="lang-rust"><strong>public fun deposit_with_account_cap&#x3C;T>(
</strong>    clock: &#x26;Clock, 
    storage: &#x26;mut Storage,
    pool: &#x26;mut Pool&#x3C;T>, 
    asset: u8,
    deposit_coin: Coin&#x3C;CoinType>,
    incentive_v2: &#x26;mut IncentiveV2,
    incentive_v3: &#x26;mut Incentive,
    account_cap: &#x26;AccountCap
) {}
</code></pre>

### withdraw\_v2

{% hint style="info" %}
This function allows other contracts to withdraw a specified amount from a lending pool. The balance object is returned, and a withdrawal event is emitted.
{% endhint %}

```rust
public fun withdraw_v2<CoinType>(
    clock: &Clock,
    oracle: &PriceOracle,
    storage: &mut Storage,
    pool: &mut Pool<CoinType>,
    asset: u8,
    amount: u64,
    incentive_v2: &mut IncentiveV2,
    incentive_v3: &mut Incentive,
    system_state: &mut SuiSystemState,
    ctx: &mut TxContext
): Balance<CoinType> {}
```

### withdraw\_with\_account\_cap\_v2

{% hint style="info" %}
This function is similar to a standard withdraw but includes an account cap limitation. The balance object is returned, and a withdrawal event is emitted.
{% endhint %}

```rust
public fun withdraw_with_account_cap_v2<CoinType>(
    clock: &Clock,
    oracle: &PriceOracle,
    storage: &mut Storage,
    pool: &mut Pool<CoinType>,
    asset: u8,
    amount: u64,
    incentive_v2: &mut IncentiveV2,
    incentive_v3: &mut Incentive,
    account_cap: &AccountCap,
    system_state: &mut SuiSystemState,
    ctx: &mut TxContext
): Balance<CoinType> {}
```

### borrow\_v2

{% hint style="info" %}
This function allows other contracts to borrow a specified amount from a lending pool. The balance object is returned, and a borrow event is emitted.
{% endhint %}

```rust
public fun borrow_v2<CoinType>(
    clock: &Clock,
    oracle: &PriceOracle,
    storage: &mut Storage,
    pool: &mut Pool<CoinType>,
    asset: u8,
    amount: u64,
    incentive_v2: &mut IncentiveV2,
    incentive_v3: &mut Incentive,
    system_state: &mut SuiSystemState,
    ctx: &mut TxContext
): Balance<CoinType> {}
```

### borrow\_with\_account\_cap\_v2

{% hint style="info" %}
This function is similar to a standard borrow but includes an account cap limitation. The balance object is returned, and the borrow event is emitted.
{% endhint %}

```rust
public fun borrow_with_account_cap_v2<CoinType>(
    clock: &Clock,
    oracle: &PriceOracle,
    storage: &mut Storage,
    pool: &mut Pool<CoinType>,
    asset: u8,
    amount: u64,
    incentive_v2: &mut IncentiveV2,
    incentive_v3: &mut Incentive,
    account_cap: &AccountCap,
    system_state: &mut SuiSystemState,
    ctx: &mut TxContext
): Balance<CoinType> {}
```

### repay

{% hint style="info" %}
This function allows other contracts to repay a specified amount of a loan. The balance object is returned, and a repay event is emitted.
{% endhint %}

```rust
public fun repay<CoinType>(
    clock: &Clock,
    oracle: &PriceOracle,
    storage: &mut Storage,
    pool: &mut Pool<CoinType>,
    asset: u8,
    repay_coin: Coin<CoinType>,
    amount: u64,
    incentive_v2: &mut IncentiveV2,
    incentive_v3: &mut Incentive,
    ctx: &mut TxContext
): Balance<CoinType> {}
```

### repay\_with\_account\_cap

{% hint style="info" %}
This function is similar to a standard repay but includes an account cap limitation.  The balance object is returned, and a repay event is emitted.
{% endhint %}

```rust
public fun repay_with_account_cap<CoinType>(
    clock: &Clock,
    oracle: &PriceOracle,
    storage: &mut Storage,
    pool: &mut Pool<CoinType>,
    asset: u8,
    repay_coin: Coin<CoinType>,
    amount: u64,
    incentive_v2: &mut IncentiveV2,
    incentive_v3: &mut Incentive,
    account_cap: &AccountCap
): Balance<CoinType> {}
```

### claim\_reward

{% hint style="info" %}
Quick Reward Claiming Using the SDK

We recommend using the SDK to claim rewards because the SDK will automatically claim all available rewards and perform off-chain indexing to optimize gas usage.

#### SDK Benefits:

* **Off-chain indexing**: Retrieves relevant rules without incurring on-chain gas costs.
* **Optimized filtering**: Selects only the necessary rule IDs before executing on-chain transactions.
  {% endhint %}

For users who want to implement customized and native reward claiming, we provide the following instructions:

### Step-by-Step Process

1. **Retrieve Claimable Rewards**&#x20;

* Use `get_user_claimable_rewards` to fetch claimable reward information.
* Parse the response using `parse_claimable_rewards`to determine RewardCoinType, coin\_types, and rule\_ids

### get\_user\_claimable\_rewards

{% hint style="info" %}
This function retrieves the claimable rewards for a user, returning detailed reward information.
{% endhint %}

```rust
struct ClaimableReward has copy, drop {
    asset_coin_type: String,
    reward_coin_type: String,
    user_claimable_reward: u256,
    user_claimed_reward: u256,
    rule_ids: vector<address>,
}

public fun get_user_claimable_rewards<RewardCoinType>(
    clock: &Clock, 
    storage: &mut Storage, 
    incentive: &mut Incentive,
    user: address
) vector<ClaimableReward> {}
```

### parse\_claimable\_rewards

{% hint style="info" %}
This function parses the claimable rewards to return the asset coin types, reward coin types, user total rewards, user claimed rewards, and rule ids.
{% endhint %}

```rust
public fun parse_claimable_rewards(claimable_rewards: vector<ClaimableReward>)
(
    vector<String>, // asset coin types
    vector<String>, // reward coin types
    vector<u256>,   // user total rewards
    vector<u256>,   // user claimed rewards
    vector<vector<address>> // rule ids
)
```

* The `coin_types` are derived from the asset tokens involved.
* The `rule_ids` are extracted from the parsed claimable rewards.

2. **Execute**

<pre><code><strong>// Reward Fund IDs
</strong>VSUI: 0x7093cf7549d5e5b35bfde2177223d1050f71655c7f676a5e610ee70eb4d93b5c
NAVX: 0x1a3f9fcfdfac10e92c99220203f7c4bb502558692f0be0f2cb5f788b4e12a6b5
SUINS: 0xc6b14b4eda9015ca69ec5f6a9688faa4f760259ce285dafe902ebe6700f5838f
DEEP: 0xc889d78b634f954979e80e622a2ae0fece824c0f6d9590044378a2563035f32f
FDUSD: 0x958dd7ad70755b10f96693bcd591d7a2cb9830a6c523baf43b3b5897664aa788
</code></pre>

### claim\_reward

```
public entry fun claim_reward<RewardCoinType>(
    clock: &Clock, 
    incentive: &mut Incentive,
    storage: &mut Storage, 
    reward_fund: &mut RewardFund<RewardCoinType>,
    coin_types: vector<String>,
    rule_ids: vector<address>,
    ctx: &mut TxContext
) {}
```

### claim\_reward\_with\_account\_cap

{% hint style="info" %}
This function is similar to a standard claim rewards but includes an account cap limitation. Rewards are distributed from the bonus pool, and a claim reward event is emitted.
{% endhint %}

<pre class="language-rust"><code class="lang-rust"><strong>public fun claim_reward_with_account_cap&#x3C;RewardCoinType>(
</strong>    clock: &#x26;Clock, 
    incentive: &#x26;mut Incentive,
    storage: &#x26;mut Storage, 
    reward_fund: &#x26;mut RewardFund&#x3C;RewardCoinType>,
    coin_types: vector&#x3C;String>,
    rule_ids: vector&#x3C;address>,
    account_cap: &#x26;AccountCap
) Balance&#x3C;RewardCoinType> {}
</code></pre>

* Sample: Provide the appropriate parameters:

```
// To claim rewards, we need to gather the same reward coin types
// and then pass the corresponding asset coin types and rule IDs.
// The expected function call should look like this:
claim_reward<VSUI>(
    ...,  // Additional parameters (e.g., clock, incentive, storage, etc.)
    coin_types: <SUI, SUI, BLUE, BLUE>,  // Expand asset types to match rule mappings
    rule_ids: <rule1, rule2, rule3, rule4>  // Flattened list of rule IDs
);
```

```
let user_a_rewards = incentive_v3::get_user_claimable_rewards(
    &clock,           
    &mut storage,     
    &mut incentive,   
    USER_A            
);
​
// Parse the retrieved claimable rewards into structured vectors
let (
    asset_coin_types,       // List of asset coin types
    reward_coin_types,      // List of corresponding reward coin types
    user_claimable_rewards, // Total claimable rewards per asset
    user_claimed_rewards,   // Already claimed rewards per asset
    rule_ids                // Associated rule IDs for each asset
) = incentive_v3::parse_claimable_rewards(user_a_rewards);
// Parse the retrieved claimable rewards into structured vectors
// Example output structure after parsing:
// (
//   <SUI, BLUE>,         // Unique asset coin types
//   <VSUI, VSUI>,        // Corresponding reward coin types
//   <claimable1, claimable2>, // Claimable rewards amounts
//   <claimed1, claimed2>, // Already claimed amounts
//   <<rule1, rule2>, <rule3, rule4>> // Rule IDs grouped by asset type
// )
```

### Full Claim Contract Demo

```
use lending_core::incentive_v3::{Self, Incentive as IncentiveV3, RewardFund};
use lending_core::storage::Storage;
use std::ascii::String;
use std::type_name;
use std::vector;
use sui::balance::{Balance};
use sui::coin::{Self};
use sui::clock::{Clock};
use sui::transfer::{Self};
use sui::tx_context::{Self, TxContext};

/// This function is used to claim reward with one coin type
/// It runs fully onchain without offchain indexing.
/// This practice is not gas optimized, and claiming reward though SDK with is recommended.
/// Params objectIds will be available on the gitbook.
    public fun claim_reward<RewardCoinType>(
        clock: &Clock,
        incentive: &mut IncentiveV3,
        storage: &mut Storage,
        reward_fund: &mut RewardFund<RewardCoinType>,
        ctx: &mut TxContext,
    ): Balance<RewardCoinType> {
        let (
            asset_coin_types,
            reward_coin_types,
            user_total_rewards,
            user_claimed_rewards,
            rule_ids,
        ) = incentive_v3::parse_claimable_rewards(
            incentive_v3::get_user_claimable_rewards(
                clock,
                storage,
                incentive,
                tx_context::sender(ctx),
            ),
        );

        let target_coin_type = &type_name::into_string(type_name::get<RewardCoinType>());

        let input_coin_types = vector::empty<String>();
        let input_rule_ids = vector::empty<address>();

        let i = 0;
        while (i < vector::length(&asset_coin_types)) {
            let asset_coin_type = vector::borrow(&asset_coin_types, i);
            let reward_coin_type = vector::borrow(&reward_coin_types, i);
            let user_total_reward = *vector::borrow(&user_total_rewards, i);
            let user_claimed_reward = *vector::borrow(&user_claimed_rewards, i);
            let rule_id = vector::borrow(&rule_ids, i);

            if (user_total_reward > user_claimed_reward && reward_coin_type == target_coin_type) {
                vector::push_back(&mut input_coin_types, *asset_coin_type);
                vector::append(&mut input_rule_ids, *rule_id);
            };

            i = i + 1;
        };

        incentive_v3::claim_reward<RewardCoinType>(
            clock,
            incentive,
            storage,
            reward_fund,
            input_coin_types,
            input_rule_ids,
            ctx,
        )
    }

    public entry fun claim_reward_entry<RewardCoinType>(
        clock: &Clock,
        incentive: &mut IncentiveV3,
        storage: &mut Storage,
        reward_fund: &mut RewardFund<RewardCoinType>,
        recipient: address,
        ctx: &mut TxContext,
    ) {
        let (
            asset_coin_types,
            reward_coin_types,
            user_total_rewards,
            user_claimed_rewards,
            rule_ids,
        ) = incentive_v3::parse_claimable_rewards(
            incentive_v3::get_user_claimable_rewards(
                clock,
                storage,
                incentive,
                tx_context::sender(ctx),
            ),
        );

        let target_coin_type = &type_name::into_string(type_name::get<RewardCoinType>());

        let input_coin_types = vector::empty<String>();
        let input_rule_ids = vector::empty<address>();

        let i = 0;
        while (i < vector::length(&asset_coin_types)) {
            let asset_coin_type = vector::borrow(&asset_coin_types, i);
            let reward_coin_type = vector::borrow(&reward_coin_types, i);
            let user_total_reward = *vector::borrow(&user_total_rewards, i);
            let user_claimed_reward = *vector::borrow(&user_claimed_rewards, i);
            let rule_id = vector::borrow(&rule_ids, i);

            if (user_total_reward > user_claimed_reward && reward_coin_type == target_coin_type) {
                vector::push_back(&mut input_coin_types, *asset_coin_type);
                vector::append(&mut input_rule_ids, *rule_id);
            };

            i = i + 1;
        };

        let balance = incentive_v3::claim_reward<RewardCoinType>(
            clock,
            incentive,
            storage,
            reward_fund,
            input_coin_types,
            input_rule_ids,
            ctx,
        );

        transfer::public_transfer(coin::from_balance(balance, ctx), recipient)
    }
```

example: [https://suivision.xyz/txblock/5Nr7nkQg8GGLepEPVRmZ2CamkUgsSoNMqDyhNGbVqjjW](https://suivision.xyz/txblock/5Nr7nkQg8GGLepEPVRmZ2CamkUgsSoNMqDyhNGbVqjjW?tab=Overview)


---

# 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://naviprotocol.gitbook.io/navi-protocol-developer-docs/smart-contract-overview/lending-core.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.
