# 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="/files/jOHoDDeZlxipVxhft1i4" %}

## 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="/files/9S5vJEnHEE6Rrtka0jLR" 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="/files/RbG0X7SOQHqclXBUbG4c" 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="/files/9hY1P7KVzSZ3YonWtcQc" 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 %}


---

# 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.kiln.fi/v1/kiln-products/omnivaults/how-to-integrate/smart-contract-interactions.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.
