# Introduction

HiYield enables access to traditional capital markets for web3 natives. Web3 natives could be anything from a new startup with team runway held in USDC or a decentralized protocol like MakerDAO with stablecoins as collateral.

We offer fully customizable solutions; everything from risk assets like Coinbase equity shares (COIN) to low risk fixed-income products like US government treasury bills. Our offerings are so flexible thanks to our smart contract infrastructure and our off-chain legal structures & relationships.

We offer a whiteglove solution to all our clients and are confident we'll be able to achieve your goals.


# Components

<figure><img src="/files/i0ybyxXCKKRvXyZXH30M" alt=""><figcaption></figcaption></figure>

HiYield infrastructure has two key components:

1.) **Onchain infrastructure:** This includes various smart contracts each with a dedicated purpose.

2.) **Offchain infrastructure:** This includes our relationships with custodians and broker dealers, as well as template traditional legal contracts


# Onchain infrastructrure

High-level description of our smart contract infrastructure

The primary smart contract for our onchain infrastructure is the Credit Vault contract, which implements the ERC4626 standard. Outside of the Credit Vault, we have a simple whitelist manager, which is used to manage access to the Credit Vault. Only users that pass KYC/KYB can access our credit vault contracts

Our credit vault contract has the following parameters, adjustable by admins:

* **Rate**: Used for yield-bearing products to set a linear rate of accrual for the redemption value
* **Borrower**: The admin wallet that is allowed to borrow funds from the pool
* **Redemption Value:** The redemption value of an hyToken

<figure><img src="https://lh7-us.googleusercontent.com/docsz/AD_4nXdWUxOBlCpf9benN0o0qEh79bxwpu11YR1UdAH6AFCf-ExKAT89owd0j0bIMOEOLmgtRyGhsPWSzHKFAhe9u48GAqBlKRxHi2SnzZLGaNCNf26lfbXabQKj1c66za-RrwqG0T5YAmTmCfHadp-gLyhbWbIC?key=gPioe2F70Hoxnj_wscZCQg" alt=""><figcaption></figcaption></figure>

<figure><img src="https://lh7-us.googleusercontent.com/docsz/AD_4nXdlwQtpxWsvkelb4K9hjROoNFmY6Pjdf_hpP7Eb5TosS7m0tVRh7lxz77hpj_Mqe6IxXysw_181E4jpvHChZ9CNvsowq_RrN75i7XXMdrUdaFPncyKsofsGkdM47xflmpH2p7SPm3FgySjqQ1rQaea8Y50?key=gPioe2F70Hoxnj_wscZCQg" alt=""><figcaption></figcaption></figure>

The typical operational flow for the onchain component involves the following:

1. Users transfer USDC to one of our credit vaults and receive a deposit token (e.g. hyTB) representing their share of the pool.
2. The deposit token immediately starts accruing interest so long as some portion of the assets have been borrowed by HiYield
3. Users can then transfer this token to approved DeFi protocols as collateral, or simply hold it in their wallet


# Offchain infrastructure

High-level description of our service providers and their role in the flow of funds

Our offchain infrastructure has 4 key components:

* **Stablecoin offboarding**: This is used to convert between fiat <> stablecoins.
* **Banking:** This is used to receive the fiat currency from the stablecoin offboarding provider
* **Custodian**: This is where all offchain assets are stored, including unspent fiat currency
* **Broker Dealer:** This is how we procure all offchain assets, such as equity and fixed-income products

The flow of funds typically works as follows:

1. HiYield borrows stablecoins from an onchain pool and sends to the stabelcoin offboarding partner
2. The offboarding partner wires fiat currency to our banking partner
3. Our banking partner wires fiat currency with additional instructions to a specific trust at the custodian
4. We contact the broker dealer to execute a trade
5. The trade is settled between the broker dealer and the custodian


# Technical

This section specifies each method in each smart contract to provide a comprehensive integrations guide.


# Credit Vault

v1.1

The Credit Vault implements the vault standard [ERC4626](https://ethereum.org/developers/docs/standards/tokens/erc-4626), so the standard documentation can be referenced for most interfaces.  Users deposit stablecoins into a vault and receive an interest-accruing deposit token. Approved borrowers can borrow from the vault and interest rates are set by admins.

### Data Source

* ERC20 standard - Security Token
* rate (uint256) the fixed interest rate which is set by the borrower. Range value (0 - 100000)
* stablecoin (address) stable coin token contract address which allowed to deposit to the pool and earn interest &#x20;
* maxPoolValue (uint256) max value can supply to the pool&#x20;
* poolValue (uint256) total underlying token&#x20;
* accrualTimestamp (uint256) timestamp that interest was last accrued at
* totalBorrowed (uint256) total borrowed token

## HiYield Credit Vault: Withdrawal Queue Feature

### Overview

If a vault does not have enough liquidity to support a withdrawal request by a lender, the transaction will not revert. Instead, withdrawal requests will be added to a list of withdrawal requests that are filled as liquidity becomes available.

<br>

<figure><img src="https://lh7-us.googleusercontent.com/docsz/AD_4nXdApHc2w27A3lLigWzC3OSX7krC2uBoV_Qto_Wz1U48U8Psr7TChBywZBhcwN1Br0V2f6pK6htyUn2_AjwhtAn8UNu6FMWn-x4wQRj_5G2-7v3_y82pO4-pw7S4-bJ_lSp46U2cC0wxNELppBHZ45CxXGNE?key=gPioe2F70Hoxnj_wscZCQg" alt="" width="375"><figcaption><p>Alice submits a withdrawal request for 75 USDC after both Bob and Charlie submitted requests<br></p></figcaption></figure>

When liquidity becomes available, either through a loan repayment or a new deposit, the withdrawal queue is checked for open withdrawal requests. Withdrawal requests are processed using the First-In-First-Out (“FIFO”) method, meaning that the oldest withdrawal request is always processed first. The amount of new liquidity dictates how many withdrawals are processed. Available liquidity should be used to fulfill withdrawal requests until there are no withdrawal requests remaining, and partial fulfillments should be supported.

<br>

<figure><img src="https://lh7-us.googleusercontent.com/docsz/AD_4nXfEqrhIvxwJF3ZxnXQlpNTjr2SoRx7uWkmNif1ofVHhxTF2vjml7un-659rqty7yxVZencgHCqip_Pq__Cro_QBwo90Qonc2j8jwTVUo8snXVKog5rvE33tEdyA_vb9pJMkE7eBRlRBhCeyeL9mqPHVDFY?key=gPioe2F70Hoxnj_wscZCQg" alt="" width="375"><figcaption><p>Greg deposits 125 USDC, which fills Bob’s request and partially fills Charlie’s request</p></figcaption></figure>

When a withdrawal request is filled, the USDC is held in the vault on behalf of the user. The user can then claim the USDC from the vault at any time. The USDC used to fill withdrawal requests should not be eligible for withdrawal by other users nor borrowers.

<div data-full-width="true"><figure><img src="https://lh7-us.googleusercontent.com/docsz/AD_4nXdmruy0pTF3x6wVLXBsRoXBhGti0_o8yLCIsUPnTHxrVB0AElUFCFL1Cr8oz9Ca_OEyAex6r0C1b4_eaZXHzTcFaicUoZlhi8_0yFGM4Z6yvLSGZXtYri8xokDCSalAMOid3m5z-mUTJbOJJETmHzdi6K1A?key=gPioe2F70Hoxnj_wscZCQg" alt="" width="375"><figcaption><p>Bob claims his 100 USDC and is removed from the withdrawal list</p></figcaption></figure></div>

## **EVM Interfaces (extension of ERC4626)**

| QUEUE DETAIL                                                                                                                                                                                                                                               |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @dev Get the withdraw request detail in queue by node index</p><p>\* </p><p>\* @return RedeemRequest{ address redeemer; uint256 amount; }</p><p>\*/</p><p>function queueDetail(uint nodeIndex) external view returns(RedeemRequest);</p> |

| QUEUE PROCESS LIMIT                                                                                                                                                                                      |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @dev Batch size of queue list being process at each transaction</p><p>\* </p><p>\* @return batch size</p><p>\*/</p><p>function queueProcessLimit() external view returns(uint256);</p> |

| CLAIMABLE WITHDRAW AMOUNT                                                                                                                                                                                        |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @dev The amount of processed withdraw an user can claim</p><p>\* </p><p>\* @return amount to claim</p><p>\*/</p><p>function claimableAssets(address owner) external view returns(uint256);</p> |

| TOTAL UNCLAIMED WITHDRAW AMOUNT                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @dev The total amount of processed withdraw users can claim</p><p>\* </p><p>\* @return total amount can claim</p><p>\*/</p><p>function totalClaimableAssets() external view returns(uint256);</p> |

| TOTAL PENDING WITHDRAW AMOUNT                                                                                                                                    |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @dev The total withdraw request amount in queue</p><p>\* </p><p>\*/</p><p>function pendingWithdrawAssets() external view returns(uint256);</p> |

| CANCEL WITHDRAW REQUEST                                                                                                                  |
| ---------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @dev Cancel withdraw request of sender</p><p>\* </p><p>\*/</p><p>function cancelWithdraw(uint nodeIndex) external;</p> |

| CANCEL WITHDRAW REQUESTS                                                                                                                                  |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @dev Cancel multi withdraw requests of sender</p><p>\* </p><p>\*/</p><p>function cancelWithdraws(uint256\[] memory nodes) external;</p> |

| GET WITHDRAW QUEUE SIZE                                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @dev Get the current size of queue list (total number of withdraw requests)</p><p>\* </p><p>\* @return the current size of queue list</p><p>\*/</p><p>function getWithdrawQueueSize() external view returns(uint256);</p> |

| GET WITHDRAW QUEUE DETAIL LIST                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @dev Get the detail of a withdraw queue batch</p><p>\* </p><p>\* @param offset\_ the index of the previous node, put 0 to start from first node</p><p>\* @param size\_ the size of the queue batch to return</p><p>*</p><p>* @returns (array of node index, array of corresponding withdraw request detail)</p><p>\*/</p><p>function getWithdrawQueueDetailList(uint256 offset\_, uint256 size\_) external view returns(uint256\[] memory, WithdrawRequest\[] memory);</p> |

| SET QUEUE PROCESS LIMIT                                                                                                                                                                                     |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @notice Sets a new queue process limit</p><p>\* @dev Admin function to set a new queue process limit</p><p>\*/</p><p>function setQueueProcessLimit(uint256 limit\_) virtual external;</p> |

| PROCESS THE FIRST BATCH OF QUEUE                                                                                                                                                                                                       |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @notice process the withdrawal queue when there is available underlying token. </p><p>\* Should be run by contract itself, anyone trigger this function.</p><p>\*/</p><p>function queueProcess() virtual public;</p> |

| BORROW FUND                                                                                                                                                                                                                                                                                                          |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @dev Method to let borrower borrow token from the pool</p><p>*</p><p>* @param receiver\_ Address to receive token</p><p>\* @param amount\_ Amount to transfer from the pool. Token in base decimal (1e18).</p><p>\*/</p><p>function borrowFund(address receiver\_, uint256 amount\_) external;</p> |

| REPAY DEBT                                                                                                                                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <p>/\*\*</p><p>\* @dev Borrower execute this function to repay token back to the pool</p><p>*</p><p>* @param amount\_ Amount of token to repay. Token in token decimal.</p><p>\*/</p><p>function repayDebt(uint256 amount\_) external;</p> |

| SET NEW INTEREST RATE                                                                                                                                                                   |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>/\*\*</p><p>\* @dev Set new rate</p><p>*</p><p>* @param newRate\_ New rate value. Rate value in range (0 - 100000)</p><p>\*/</p><p>function setRate(uint256 newRate\_) external;</p> |

| EVENTS                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <p>event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);</p><p>event Withdraw(</p><p>   address indexed sender,</p><p>   address indexed receiver,</p><p>   address indexed owner,</p><p>   uint256 assets,</p><p>   uint256 shares</p><p>);</p><p>event BorrowFund(address, uint256);</p><p>event Repay(address, uint256);</p><p>event MaxPoolValue(uint256, uint256);</p><p>event SetQueueProcessLimit(uint256);</p><p>event AddQueue(address, uint256);</p><p>event ClaimWithdraw(address, uint256);</p><p>event CancelQueue(address, uint256);</p><p>event ProcessedQueue(uint256 indexed node, address indexed receiver, uint256 assets);</p> |

## Stellar Soroban Interfaces&#x20;

**Build contracts:**

```
soroban contract build
```

**Test contracts:**

```
 cargo test --package credit-vault
```

#### Contract Interface

The contract implemented [ERC4626](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/) and follows Stellar contract convention, `example` totalAssets changed to total\_assets, and with additional interfaces:

**ERC4626 interface**

```
fn deposit(e: Env, from: Address, assets: i128, receiver: Address) -> i128

fn mint(e: Env, from: Address, shares: i128, receiver: Address) -> i128

fn max_withdraw(e: Env, owner: Address) -> i128

fn withdraw(e: Env, from: Address, assets: i128, receiver: Address, owner: Address) -> i128

fn redeem(e: Env, from: Address, shares: i128, receiver: Address, owner: Address) -> i128

fn max_redeem(e: Env, owner: Address) -> i128

fn available_assets(e: Env) -> i128

fn convert_to_shares(e: Env, assets: i128) -> i128

fn convert_to_assets(e: Env, shares: i128) -> i128

fn asset(e: Env) -> Address

fn total_assets(e: Env) -> i128

fn convert_to_shares(e: Env, assets: i128) -> i128

fn convert_to_assets(e: Env, shares: i128) -> i128

fn preview_deposit(e: &Env, assets: i128) -> i128

fn preview_mint(e: &Env, shares: i128) -> i128

fn preview_withdraw(e: &Env, assets: i128) -> i128

fn preview_redeem(e: &Env, shares: i128) -> i128
```

**total\_claimable\_assets**

```
fn total_claimable_assets(e: Env) -> i128
```

The total amount of processed withdraw users can claim

**queue\_process**

```
fn queue_process(e: Env)
```

Process the withdrawal queue when there is available underlying token

**get\_withdraw\_queue\_detail\_list**

```
fn get_withdraw_queue_detail_list(e: Env, offset: u128, size: u128) -> (Vec<u128>, Vec<WithdrawRequest>)
```

Get the detail of a withdraw queue batch

* @param offset\_ the index of the previous node, put 0 to start from first node
* @param size\_ the size of the queue batch to return

**get\_withdraw\_queue\_size**

```
fn get_withdraw_queue_size(e: Env) -> u128
```

Get the current size of queue list (total number of withdraw requests)

**cancel\_withdraw**

```
fn cancel_withdraw(e: Env, from: Address, node: u128)
```

Cancel withdraw request of sender by queue index

**claimable\_assets**

```
fn claimable_assets(e: Env, owner: Address) -> i128
```

The amount of processed withdraw an user can claim

**total\_borrowed\_assets**

```
fn total_borrowed_assets(e: Env) -> i128
```

Returns the total amount of assets borrowed by pool

**pending\_withdraw\_assets**

```
fn pending_withdraw_assets(e: Env) -> i128
```

Returns the total amount assets of pending withdraw requests

**claim\_withdraw**

```
fn claim_withdraw(e: Env) -> i128
```

This function claims the processed amount of assets from previous withdraw/redeem request of sender

**token\_address**

```
fn token_address(e: Env) -> i128
```

Returns the vault token address which presents the shares of each user in the vault

**rate**

```
fn rate(e: Env) -> u32
```

Returns the interest rate value of the pool (0 - 10000).


# Contract Addresses

## **Credit Vault:**

#### Mainnet&#x20;

* Stellar
  * Treasury bill vault: CAAPC4ETIO7HFU5EI6HUHR6V6J5AYQ5NVMM7X2NTI6J7R2STOLOCRU5W
* Ethereum
  * Treasury bill vault: 0xaF5Baa225765B2ef3eB446aEAB87e02DFBcFEAc2
* Avax&#x20;
  * Treasury bill vault: 0x8475509d391e6ee5A8b7133221CE17019D307B3E
  * Investment grade bonds vault: 0xce6050625fe3F79bBfC4d236aBAaBE51AB59e660

#### Testnet

* Ethereum
  * Sepolia: 0x140a396560B1e35752faD19f4539c6f3AfbC5FBc
* Avax&#x20;
  * Fuji: 0x7f5C333D5519ee7C15c34997cA9232428bF7a6c1


# Community Resources

## Official Links

**Landing Page:** <https://www.hiyield.xyz/>

**Mainnet App:** <https://app.hiyield.xyz/offerings>

**Twitter:** <https://twitter.com/hiyield_xyz>

**Discord:** <https://discord.gg/Kz5vd8enX>


# Legal Structure

## Offerings Legal Structure

The investment contract for HiYield products can be custom tailored, based on flexible legal frameworks designed by Manatt, Phelps & Phillips, LLP. The offchain assets for each vault are held in SPVs managed by [WSFS Bank](https://www.wsfsbank.com/), and all capital markets activity is executed through [Raymond James](https://www.raymondjames.com/).


