> For the complete documentation index, see [llms.txt](https://docs.satay.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.satay.finance/strategy-implementations/strategy.md).

# Echelon Simple

## 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](/technical-overview/vault-module.md#functions) 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](/technical-overview/vault-module.md#functions) 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](#internal-functions) 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](#internal-functions) function.
* `vault_report<CoinType>(account: &signer, strategy: Object<BaseStrategy>)`: Reports strategy performance to the vault by calling the [report](/technical-overview/vault-module.md#internal-functions) 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](#internal-functions)). Finally, calls the [complete\_withdrawal](/technical-overview/base-strategy-module.md#withdrawal-management) 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](#internal-functions)). Finally, calls the [complete\_withdrawal\_coin](/technical-overview/base-strategy-module.md#withdrawal-management) 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](/blocks/echelon.md) 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](/blocks/echelon.md) 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](/blocks/echelon.md#market-operations) 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](/blocks/echelon.md#market-operations) 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](/technical-overview/base-strategy-module.md#harvest-management) or [report\_harvest\_loss](/technical-overview/base-strategy-module.md#harvest-management) from the `satay::base_strategy` module.
