# Reserve

{% hint style="warning" %}
This section describes the state of the module as of April 2023.&#x20;
{% endhint %}

* **Module Name:** Reserve Module
* **Contract Sources:**&#x20;
  * [Reserve.sol](https://github.com/Kolektivo/kolektivo-monetary-contracts/blob/development/src/Reserve.sol)
  * [CuracaoReserveToken.s](https://github.com/Kolektivo/kolektivo-monetary-contracts/blob/development/src/CuracaoReserveToken.sol)
  * [BalancerV2Proxy.sol](https://github.com/Kolektivo/kolektivo-monetary-contracts/blob/development/src/dex/BalancerV2Proxy.sol)
  * Oracles

<figure><img src="/files/YerNMQz4tuiBQf8JrIFQ" alt=""><figcaption><p>Zoom on the Reserve smart contract architecture</p></figcaption></figure>

<details>

<summary>Table of Contents</summary>

[Summary](#summary)

[Module Details](#module-details)

[Reserve](#reserve)

[Reserve Token](#reserve-token)

[Proxy Contract](#proxy-contract)

[Oracles](#oracles)

* [cUSD/Celo Oracle](#cusd-celo-oracle)
* [kCUR Oracle](#kcur-oracle)

[Back-End Services](#back-end-services)

* [cUSD/Celo Data Provider Service](#cusd-celo-data-provider-service)
* [kCUR Data Provider Service](#kcur-data-provider-service)
* [Floor and Ceiling Arbitrage Services](#floor-and-ceiling-arbitrage-services)

[Failure Modes](#failure-modes)

</details>

## Summary

The Reserve module is a governable and parametrizable financial entity that produces a token, allowing for local monetary policies to be conducted.

The Reserve module is understood as the combination of a locally governed and parametrizable Reserve, producing a Reserve token (kCUR), whose price range is managed by a Proxy contract interfacing with a [Symmetric](https://symmetric.finance/) pool.

The Reserve takes influence from [TempleDAO](https://templedao.link/), allowing for mechanisms such as bonding, token price floors, and ceillings.

## Module Details

The Reserve module has 4 core components consisting of the `Reserve.sol`,  `CuracaoReserveToken.sol,` and `BalancerV2Proxy.sol`contracts. On top of this, several oracles regularly update the contracts with crucial data, and a few back-end services are run.&#x20;

{% embed url="<https://github.com/Kolektivo>" %}
Kolektivo monetary contracts on GitHub.
{% endembed %}

## Reserve

{% hint style="info" %}
If you want to know more about the concept of Reserve, please refer to [this section.](/kolektivo-docs/tools/live-tools/reserve.md)
{% endhint %}

The `Reserve.sol` contract is a custom creation that has been influenced by the [TempleDAO](https://github.com/TempleDAO?q=\&type=all\&language=\&sort=) Reserve contract, which itself takes itself inspiration into the [OlympusDAO](https://github.com/OlympusDAO) Reserve contract.&#x20;

It is an ownable contract owned by the Kolektivo multi-sig that manages a fractional receipt money using ERC20 tokens and/or ERC721 NFTs as collateral. The contract includes specific features that enables the conduction of local monetary policies. Primary features are listed in the table below. For more details please [see the contract on GitHub](https://github.com/Kolektivo/kolektivo-monetary-contracts/blob/development/src/Reserve.sol).

<table><thead><tr><th width="210.33333333333331">Feature</th><th width="250">Content or description</th><th>Restriction</th></tr></thead><tbody><tr><td><code>MinBacking</code></td><td>Modifiable minimum backing of the reserve token, which can be understood as a limit to the leverage.</td><td>Contract owner</td></tr><tr><td><code>incurDebt</code></td><td>Minting of the reserve token.</td><td>Contract owner</td></tr><tr><td><code>Minting Functions</code></td><td>Minting of assets restricted by a given vesting period.</td><td>Inhibited for this MVP</td></tr><tr><td><code>payDebt</code></td><td>Burning of the reserve token</td><td>Contract owner</td></tr><tr><td><code>Asset Management</code></td><td>Register and deregister reserve assets. Each of them has its own oracle.</td><td>Contract owner</td></tr><tr><td><code>WithdrawERC20</code>, <code>WithdrawERC721Id</code></td><td>Withdraw assets from the reserve.</td><td>Contract owner</td></tr><tr><td><code>Bond Functions</code></td><td>Bond assets — i.e. increase the value of the Reserve by depositing assets in exchange for the Reserve token.</td><td>Inhibited for this MVP</td></tr><tr><td><code>Redeem Functions</code></td><td>Redeem assets — i.e. decrease the value of the Reserve by depositing the Reserve token in exchange for assets.</td><td>Inhibited for this MVP</td></tr><tr><td><code>Bonding &#x26; Redeeming Management</code></td><td>List and delist assets that are bondable and redeemable. Set limits to bonding and redeeming.</td><td>Inhibited for this MVP</td></tr><tr><td><code>Discount Functions</code></td><td>Application of discount (if any) on the price of the bonded assets as an incentive to bond.</td><td>Inhibited for this MVP</td></tr><tr><td><code>Discount Management</code></td><td>Set bonding discounts — i.e. discount on price as an incentive to bound.</td><td>Inhibited for this MVP</td></tr><tr><td><code>Vesting Management</code></td><td>Set bonding vesting and vesting vault.</td><td>Inhibited for this MVP</td></tr></tbody></table>

### Error Messages

| Code                                   | Description                                                                    |
| -------------------------------------- | ------------------------------------------------------------------------------ |
| `Reserve__InvalidRecipient`            | Given token recipient invalid                                                  |
| `Reserve__InvalidAmount`               | Given token amount invalid                                                     |
| `Reserve__ERC20NotRegistered`          | Given ERC20 token address not registered                                       |
| `Reserve__ERC721IdNotRegistered`       | Given ERC721Id instance not registered                                         |
| `Reserve__ERC20NotBondable`            | Given ERC20 token address not bondable                                         |
| `Reserve__ERC721IdNotBondable`         | Given ERC721Id instance not bondable                                           |
| `Reserve__ERC20NotRedeemable`          | Given ERC20 token address not redeemable                                       |
| `Reserve__ERC721IdNotRedeemable`       | Given ERC721Id instance not redeemable                                         |
| `Reserve__ERC20BondingLimitExceeded`   | Bonding opeation exceeded reserve's bondng limit for given ERC20 token address |
| `Reserve__ERC20RedeemLimitExceeded`    | Redeem operation exceeded reserve's redeem limit for given ERC20 token address |
| `Reserve__ERC20BalanceNotSufficient`   | Reserve's balance for given ERC20 token address no sufficient                  |
| `Reserve__MinimumBackingLimitExceeded` | Reserve's minimum backing limit exceeded                                       |
| `Reserve__InvalidOracle`               | Reserve received invalid oracle response                                       |

## Reserve token

The [Reserve token](/kolektivo-docs/tools/framework-tokens/reserve-token.md) is a vanilla ERC-20 token backed by the Reserve's assets. In the context of the first deployment of the Kolektivo smart contracts for Curaçao, the Reserve Token is called kCUR.&#x20;

{% hint style="info" %}
**Why decoupling Reserve and Reserve Token?**

The Reserve is decoupled from the Reserve Token. The justification for this architectural decision is to decouple the monetary value from the risk of the monetary policies — e.g. if the monetary policy  fails, the decoupling makes it possible to swap out the reserve and keep the token.&#x20;
{% endhint %}

The `CuracaoReserveToken.sol` contract defines a `mintBurner` role that is allowed to burn and mint kCUR. The `mintBurner` role is managed by the contract owner — in our case, the Kolektivo multi-sig. Note however that multiple `mintBurner` roles may be added, i.e. the `Reserve.sol` and Proxy Pool contracts. For more details, please refer to the [Reserve token contract on GitHub](https://github.com/Kolektivo/kolektivo-monetary-contracts/blob/development/src/ReserveToken.sol).

To implement the vesting periods define by the Kolektivo multi-sig in the Reserve, a [vesting contract](https://github.com/Kolektivo/kolektivo-monetary-contracts/blob/development/src/vesting/TimeLockVault.sol) restricts the minting of kCUR. Similarly to OlympusDAO, this is used as a protective measure to avoid users to continually bond assets. As the bonding and redeeming functions are inhibited for the MVP, the vesting contract won't be called.

### Error Messages

| Code                             | Description                               |
| -------------------------------- | ----------------------------------------- |
| `ReserveToken__InvalidRecipient` | Invalid token recipient                   |
| `ReserveToken__InvalidAmount`    | Invalid token amount                      |
| `ReserveToken__NotMintBurner`    | Function is only callable by `mintBurner` |

## Proxy contract

The `BalancerV2Proxy.sol` contract is a custom contract meant to implement kCUR's price ceiling and floor mechanisms.&#x20;

{% hint style="info" %}
**Why a Proxy and not an Automated Market Maker (AMM)?**

Compare the two options:

* **TempleDAO approach:** Token's ceiling and floor mechanisms are enforced via a custom AMM (Uniswap V2 fork). Users can trade on other public markets, but with sub-optimal rates. On top of this, TempleDAO has to provide liquidity for this special pool.&#x20;
* **Kolektivo approach:** Token's ceiling and floor mechanisms are enforced via a Proxy. The user can interact with any public market, like Ubeswap or Balancer; the logic is implemented in the Proxy contract. People can choose not to use the Proxy contract but are incentivized to do so due to better rates, especially at or below the floor.
  {% endhint %}

The Proxy contract interacts with the Symmetric pool to implement kCUR's price floor and ceiling. The Reserve's contract's owner defines kCUR's [price floor](#user-content-fn-1)[^1] as the total USD valuation of backing assets / total kCUR supply. The Proxy contract implements this floor, and on top of this has a multiplier for the minimum backing defined which will define the price ceiling that it will implement. For more details, please refer to the [contract on GitHub.](https://github.com/Kolektivo/kolektivo-monetary-contracts/blob/development/src/dex/UniswapV2Proxy.sol)

The use of a proxy contract to arbitrage is incentiviced by means of a discount: Whenever a buy or sell order is done which would trigger either the floor or ceiling mechanism, part of the order will be rerouted to the Reserve contract either minting or burning kCUR. The graphics below detail the floor and ceiling mechanisms flows.

<figure><img src="/files/5yLYcZHUHtVEglTij1zN" alt=""><figcaption><p>Ceiling mechanism</p></figcaption></figure>

<figure><img src="/files/Tvy3qdt5A4JEffiAL2b8" alt=""><figcaption><p>Floor mechanism</p></figcaption></figure>

In addition to this, and in order for kCUR's price to remain withing its price ceiling and floor, the Proxy contract is reinforced by a [Floor and Ceiling Arbitrage Back-End Service](#floor-and-ceiling-arbitrage-services) described in the Back-End Services section below.&#x20;

## Oracles

Two oracles are necessary for the good functionment of the Reserve module: a cUSD<mark style="color:red;">/Celo</mark> oracle, and a kCUR oracle.&#x20;

<figure><img src="/files/aeMurBImmidYXAyV5EuU" alt=""><figcaption><p>Oracle flow</p></figcaption></figure>

#### cUSD Oracle

For the Reserve to function correctly, it is important that the assets that it contains are priced correctly. For that, the Reserve frenquently queries the cUSD oracle for the price data of the stable coin. A cUSD Data Provider [back-end service](#back-end-services) frequently pushes reports into the cUSD oracle about the state of the tokens' prices on-chain. This protects the Reserve from arbitrage opportunities that could occcur in the case of wrong token price reporting.&#x20;

#### kCUR Oracle

As kCUR external price isn't known by the Reserve, it is important to have a kCUR oracle frenquently informing the Reserve. A kCUR Data Provider [back-end service](#back-end-services) regurlaly pushes reports about the state of kCUR's price in the kCUR Symmetric pool to the kCUR oracle. The  Reserve frenquently queries the kCUR oracle to be updated about the state of kCUR's price. This protects the Reserve from arbitrage opportunities that could occcur in the case of wrong token price reporting.&#x20;

## Back-End Services

{% hint style="info" %}
As of April 2023, Kolektivo deployed a number of off-chain backend services that will observe specific contracts and APIs, execute transactions and reports asset data on-chain.
{% endhint %}

### cUSD/Celo Data Provider Service

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

#### Summary

This back-end service is used to get the market price of cUSD/Celo on chain. The market price will be pulled by backend service from a public API and send as payload to the cUSD/Celo oracle contract. Whenever there is need for an on-chain price for the assets, the oracle contract will be queried.

#### Functions

* The service pulls the asset data from [Coingecko](https://www.coingecko.com/fr).
* The service is able to handle Coingecko timeouts.
* The service queries the API, and than publish the price data to the Oracle contract every 120 seconds.
* The service formats the price data payload to the contract in 18 decimals format.

### kCUR Data Provider Service

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

#### Summary

The service is used to get the market price for kCUR to the oracle. This back-end service is able to pull the kCUR market price from a specific Symmetric pool address. The service queries the Symmetric pool, and than publish the price data to the oracle contract.

#### Functions

* The market price pulls from the Symmetric kCUR pool contract and sent as payload to the oracle contract every 120 seconds.
* Whenever there is a need for an on-chain price for kCUR, the oracle contract is queried.
* The service formats the payload to the contract in 18 decimals format.

### Floor and Ceiling Services

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

#### Summary

The Reserve token kCUR has a floor and ceiling price. To ensure that market price stays within the floor and ceiling price range, a floor and ceiling back-end service is necessary. The service queries price data from the kCUR oracle, the floor price from the reserve contract, the ceiling price from the Proxy contract, and perform kCUR buy or sell orders to maintain its price between floor and ceiling.&#x20;

#### Functions

* The service holds a certain amount of kCUR to trigger the floor/ceiling mechanism.
* The service is able to query the price from the kCUR oracle periodically.
* The service is able to query the ceiling price for kCUR from the Proxy contract.
* The service is able to query the floor price from the Reserve contract.
* The service is able to decide to buy or sell kCUR for cUSD when ever the ceiling or floor is reached.

## Failure Modes

{% hint style="danger" %}
Please note that this experimental MVP software is provided on an "as is" and "as available" basis. As this module is an first attempt, be aware that different failures may occur. We do not give any warranties and will not be liable for any loss incurred through any use of this codebase.
{% endhint %}

[^1]:


---

# 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://kolektivo.gitbook.io/kolektivo-docs/advanced/smart-contracts/monetary-system/reserve.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.
