# Echelon Simple Lend

## Overview

The `echelon_simple::strategy` module implements a simple lending strategy for the Echelon protocol. It allows deposits and withdrawals of both `Coin` and `FungibleAsset` types, and manages lending positions in Echelon markets.

## Strategy Module

### Structs

#### Witness

Internal witness type for strategy creation.

```rust
struct Witness has drop {}
```

#### EchelonStrategy

Core strategy struct storing vault and market references.

```rust
struct EchelonStrategy has key {
    auth_ref: AuthRef,
    vault: Object<Vault>,
    market: Object<Market>
}
```

### Events

* **StrategyCreated**: Event emitted when a new strategy is created.

### Error Codes

* `ENOT_AUTHORIZED`: Not authorized to perform the operation
* `EINVALID_AMOUNT`: Invalid amount specified
* `EINSUFFICIENT_BALANCE`: Insufficient balance to perform the operation
* `EINVALID_ASSET_METADATA`: Invalid asset metadata
* `EUNSUPPORTED_ASSET_TYPE`: Unsupported asset type
* `EINVALID_ASSET_TYPE`: Invalid asset type
* `EVAULT_MISMATCH`: Invalid vault specified
* `EWITHDRAWAL_ACCOUNT_MISMATCH`: Invalid withdrawal account specified
* `ECANNOT_EXCEED_DEBT`: Cannot exceed the strategy debt

### Public Functions

#### Strategy Creation and Management

* `create(account: &signer, vault: Object<Vault>, market: Object<Market>, debt_limit: u64)`: Creates a new instance of the strategy for the specified vault. Only callable by governance account.

#### Direct Deposit Functions

* `deposit_fa(account: &signer, strategy: Object<BaseStrategy>, amount: u64)`: Withdraws the strategy's base asset (FungibleAsset) from signer's primary store and deposits this directly into the strategy. The minted strategy shares are deposited into the signer's primary fungible store.
* `deposit_coin<CoinType>(account: &signer, strategy: Object<BaseStrategy>, amount: u64)`: Withdraws the strategy's base asset (Coin) from signer's primary store and deposits this directly into the strategy. The minted strategy shares are deposited into the signer's primary fungible store.

#### Vault Deposit Functions

* `vault_deposit_coin<CoinType>(account: &signer, strategy: Object<BaseStrategy>, amount: u64)`: Deposits the strategy's base asset (Coin) from the vault into the strategy. Must be called with the vault's signer (typically via router). The minted strategy shares are deposited into the vault's primary fungible store.
* `vault_deposit_fa(account: &signer, strategy: Object<BaseStrategy>, amount: u64)`: Deposits the strategy's base asset (FungibleAsset) from the vault into the strategy. Must be called with the vault's signer (typically via router). The minted strategy shares are deposited into the vault's primary fungible store.

#### Direct Withdrawal Functions

* `withdraw_fa(account: &signer, strategy: Object<BaseStrategy>, amount: u64, max_loss: Option<u64>)`: Withdraws the strategy's base asset (FungibleAsset) directly from the strategy by redeeming the specified amount of strategy shares from the signer's primary fungible store.
* `withdraw_coin<CoinType>(account: &signer, strategy: Object<BaseStrategy>, amount: u64, max_loss: Option<u64>)`: Withdraws the strategy's base asset (Coin) directly from the strategy by redeeming the specified amount of strategy shares from the signer's primary fungible store.

#### Vault Withdrawal Functions

* `vault_withdraw_coin<CoinType>(account: &signer, request: &mut WithdrawalRequest, strategy: Object<BaseStrategy>, amount: u64, max_loss: Option<u64>): Coin<CoinType>`: Withdraws the strategy's base asset (Coin) from a vault's strategy. Must be called with the vault's signer (typically via router). Processes withdrawal through the withdraw\_strategy\_shares function in the `satay::vault` module.
* `vault_withdraw_fa(account: &signer, request: &mut WithdrawalRequest, strategy: Object<BaseStrategy>, amount: u64, max_loss: Option<u64>): FungibleAsset`: Withdraws the strategy's base asset (FungibleAsset) from a vault's strategy. Must be called with the vault's signer (typically via router). Processes withdrawal through the withdraw\_strategy\_shares function in the `satay::vault` module.

#### Strategy Operations

* `tend_coin<CoinType>(account: &signer, strategy: Object<BaseStrategy>)`: Tends the strategy's position by depositing idle Coin into the market.
* `tend_fa(account: &signer, strategy: Object<BaseStrategy>)`: Tends the strategy's position by depositing idle FungibleAsset into the market.
* `harvest<CoinType>(account: &signer, strategy: Object<BaseStrategy>)`: Claims and reinvests rewards for Coin, reports profits/losses with internal handle\_harvest\_pnl function.
* `harvest_fa(account: &signer, strategy: Object<BaseStrategy>, reward_metadata: Object<Metadata>)`: Claims and reinvests rewards for FungibleAsset, reports profits/losses with internal handle\_harvest\_pnl function.
* `vault_report<CoinType>(account: &signer, strategy: Object<BaseStrategy>)`: Reports strategy performance to the vault by calling the report function in the `satay::vault` module.

#### Getters

* `get_market(strategy: Object<BaseStrategy>): Object<Market>`: Returns the market associated with the strategy.

### Internal Functions

* `borrow_strategy(strategy: Object<BaseStrategy>): &EchelonStrategy`: Returns a reference to the strategy data.
* `deposit_coin_internal<CoinType>(strategy: &EchelonStrategy, coin: Coin<CoinType>): FungibleAsset`: Internal function for Coin deposits. Mints and returns strategy shares.
* `deposit_fa_internal(strategy: &EchelonStrategy, asset: FungibleAsset): FungibleAsset`: Internal function for FungibleAsset deposits. Mints and returns strategy shares.
* `withdraw_fa_internal(strategy_ref: &EchelonStrategy, asset: FungibleAsset, max_loss: Option<u64>): FungibleAsset`: Internal function for FungibleAsset withdrawals. Tries to complete withdrawal with idle assets, withdraws from depoits in the yield source if needed (using market\_withdraw\_fa\_internal). Finally, calls the complete\_withdrawal function from `satay::base_strategy` to complete the withdrawal.
* `withdraw_coin_internal<CoinType>(strategy_ref: &EchelonStrategy, asset: FungibleAsset, max_loss: Option<u64>): Coin<CoinType>`: Internal function for Coin withdrawals. Tries to complete withdrawal with idle assets, withdraws from depoits in the yield source if needed (using market\_withdraw\_fa\_internal). Finally, calls the complete\_withdrawal\_coin function from `satay::base_strategy` to complete the withdrawal.
* `market_withdraw_coin_internal<CoinType>(strategy_ref: &EchelonStrategy, amount: u64): Coin<CoinType>`: Internal function for withdrawing Coin from market. Calculates how much shares need to be redeemed to withdraw the right amount of Coin, then calls withdraw in `echelon_block::echelon_block` to redeem the shares for Coin.
* `market_withdraw_fa_internal(strategy_ref: &EchelonStrategy, amount: u64): FungibleAsset`: I nternal function for withdrawing FungibleAssets from market. Calculates how much shares need to be redeemed to withdraw the right amount of FungibleAsset, then calls withdraw\_fa in `echelon_block::echelon_block` to redeem the shares for Coin.
* `market_deposit_coin_internal<CoinType>(strategy: &EchelonStrategy, coin: Coin<CoinType>)`: Internal function for depositing Coin to market using the supply function from `echelon_block::echelon_block`.
* `market_deposit_fa_internal(strategy: &EchelonStrategy, asset: FungibleAsset)`: Internal function for depositing FungibleAssets to market using the supply\_fa function from `echelon_block::echelon_block`.
* `handle_harvest_pnl(request: &mut HarvestRequest, strategy: Object<BaseStrategy>, market: Object<Market>)`: Internal function for calculating and reporting harvest profits/losses using either report\_harvest\_profit or report\_harvest\_loss from the `satay::base_strategy` module.


---

# 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.canopyhub.xyz/canopys-four-layers/strategy-layer/simple-lending-strategy/echelon-simple-lend.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.
