# Smart contract interactions

{% hint style="warning" %}
Kiln OmniVaults smart contracts integrate the [Chainalysis Oracle for sanctions screening](https://go.chainalysis.com/chainalysis-oracle-docs.html) on all chains where it's available. The oracle actively monitors and screens addresses against up-to-date sanctions lists, ensuring that any sanctioned addresses are automatically restricted from interacting with Kiln OmniVaults vaults.
{% endhint %}

Kiln OmniVaults Vault smart contracts adhere to the [ERC4626](https://docs.openzeppelin.com/contracts/4.x/erc4626) standard, making integration straightforward. When users deposit tokens, they receive shares representing their position. For a better user experience, we recommend abstracting any asset-to-share conversions and always displaying asset amounts on the UI instead of share amounts.

Here is the ABI of the Vault contract:

{% file src="<https://1911902555-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fnye3yqpuOzdfrtWAlwng%2Fuploads%2FXNZVviaAXZl0wa02nxYY%2Fvault.abi.json?alt=media&token=1819cb8b-00dd-4fbe-a9e9-0bfce3bfe8ee>" %}

## 1. Depositing

Before depositing 'x' assets, ensure the user has approved the vault to spend 'x' on their behalf via the asset contract.

* **Check Allowance**: Call the `allowance(address owner, address spender) → uint256` function on the ERC20 asset contract.
* **Increase Allowance**: Use the `approve(address spender, uint256 amount) → bool` function on the ERC20 asset contract to increase the allowance to the desired deposit amount.

Before depositing X assets, you must make sure the user approved the vault to spend X on its behalf on the asset contract.

:warning: **Note**: Only have the user approve the exact amount they intend to deposit into the vault.

<figure><img src="https://1911902555-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fnye3yqpuOzdfrtWAlwng%2Fuploads%2FgYrC7QhKzzRgnVzezmFi%2FFrame%20127%20(3).svg?alt=media&#x26;token=b4b58276-4e90-47d3-b993-392880790d32" alt=""><figcaption><p>User deposits ERC20 and receives shares</p></figcaption></figure>

To deposit an amount of the vault's ERC20, the transaction sender must call the `deposit(uint256 assets, address receiver)` function, where `assets` is the amount of ERC20 to deposit in the strategy, and `receiver` is the address that should own the deposited position.

(Optional) If you need to compute the amount of shares the user will receive before making a deposit, you can preview the amount by calling `previewDeposit(uint256 assets)`, where `assets` is the amount of ERC20 to deposit.

## 2. Get the balance in assets

<details>

<summary>Using the reporting API</summary>

```
curl https://api.kiln.fi/v1/defi/v1/stakes?users=$ADDRESS1&vaults=$VAULT1,$VAULT2 \
   -H "Authorization: Bearer $API_TOKEN"

200
{
  "stakes": [
    {
      "current_balance": 1880000,
      "asset": "0x94a9d9ac8a22534e3faca9f4e7f2e2cf85d5e4c8",
      "total_rewards": 42000,
      "asset_symbol": "USDC",
      "total_deposited_amount": 1980000,
      "total_withdrawn_amount": 100000,
      "vault": "0x9aB5F9101a3C1B868e2c422E294cc2ee685551D5",
      "chain": "ethereum"
    },
    {
      "current_balance": 1880000,
      "asset": "0x94a9d9ac8a22534e3faca9f4e7f2e2cf85d5e4c8",
      "total_rewards": 1330,
      "asset_symbol": "USDC",
      "total_deposited_amount": 1980000,
      "total_withdrawn_amount": 100000,
      "vault": "0x8aB6F9101a3C1B868e2c422E294cc2ee686662Ab",
      "chain": "ethereum"
    }
  ]
}
```

</details>

<details>

<summary>Using contract view functions</summary>

1. To check the position balance in shares, call the `balanceOf(address owner)` function, where `owner` is the address of the position owner.
2. To determine the amount of ERC20 the position is worth, call the `previewRedeem(uint256 shares)` function, where `shares` is the amount of shares to redeem. This will return the equivalent amount of ERC20.

</details>

## 3. Exiting a position

#### Case 1: exit part of a position

<figure><img src="https://1911902555-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fnye3yqpuOzdfrtWAlwng%2Fuploads%2Fn9oNmOAwomgvJgOlw5Bw%2FFrame%20128%20(3).svg?alt=media&#x26;token=b5f64c38-f63e-4e0f-9a8d-55cff9e08909" alt=""><figcaption><p>Withdraw ERC20 value using assets as input value</p></figcaption></figure>

In this case, we expect the user to input the amount of ERC20 they want to withdraw and then call the `withdraw(uint256 assets, address receiver, address owner)` function. Here:

* `assets` is the amount of ERC20 to withdraw.
* `receiver` is the address that will receive the redeemed ERC20.
* `owner` is the address of the position owner (the same as the transaction sender).

#### Case 2: exit a position fully

<figure><img src="https://1911902555-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fnye3yqpuOzdfrtWAlwng%2Fuploads%2FeaFSdneKBhU3tyMXP5yL%2FFrame%20128%20(2).svg?alt=media&#x26;token=0312dc12-0026-454c-b5ae-81b13d748648" alt=""><figcaption><p>Redeem ERC20 value using shares as input value</p></figcaption></figure>

To exit the entire position, the best approach is to determine the user's share amount and redeem it. Follow these steps:

1. Retrieve the share amount of the user's position using the `balanceOf(address owner)` function, where `owner` is the address of the position owner.
2. Redeem the shares by calling the `redeem(uint256 shares, address receiver, address owner)` function, where:
   * `shares` is the amount of shares to redeem.
   * `receiver` is the address that will receive the redeemed ERC20.
   * `owner` is the address of the position owner (the same as the transaction sender).

{% hint style="warning" %}
Using the `withdraw` function instead of the `redeem` function may prevent the user from fully exiting their position, as the shares-to-assets rate might change between the input and the actual block when the transaction is included.
{% endhint %}
