Reserve
Explore the anatomy of the Reserve module and understand certain architectural decisions that relate to it.
Last updated
Explore the anatomy of the Reserve module and understand certain architectural decisions that relate to it.
Last updated
This section describes the state of the module as of April 2023.
Module Name: Reserve Module
Contract Sources:
Oracles
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 pool.
The Reserve takes influence from TempleDAO, allowing for mechanisms such as bonding, token price floors, and ceillings.
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.
If you want to know more about the concept of Reserve, please refer to this section.
The Reserve.sol
contract is a custom creation that has been influenced by the TempleDAO Reserve contract, which itself takes itself inspiration into the OlympusDAO Reserve contract.
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.
Feature | Content or description | Restriction |
---|---|---|
| Modifiable minimum backing of the reserve token, which can be understood as a limit to the leverage. | Contract owner |
| Minting of the reserve token. | Contract owner |
| Minting of assets restricted by a given vesting period. | Inhibited for this MVP |
| Burning of the reserve token | Contract owner |
| Register and deregister reserve assets. Each of them has its own oracle. | Contract owner |
| Withdraw assets from the reserve. | Contract owner |
| Bond assets β i.e. increase the value of the Reserve by depositing assets in exchange for the Reserve token. | Inhibited for this MVP |
| Redeem assets β i.e. decrease the value of the Reserve by depositing the Reserve token in exchange for assets. | Inhibited for this MVP |
| List and delist assets that are bondable and redeemable. Set limits to bonding and redeeming. | Inhibited for this MVP |
| Application of discount (if any) on the price of the bonded assets as an incentive to bond. | Inhibited for this MVP |
| Set bonding discounts β i.e. discount on price as an incentive to bound. | Inhibited for this MVP |
| Set bonding vesting and vesting vault. | Inhibited for this MVP |
Code | Description |
---|---|
| Given token recipient invalid |
| Given token amount invalid |
| Given ERC20 token address not registered |
| Given ERC721Id instance not registered |
| Given ERC20 token address not bondable |
| Given ERC721Id instance not bondable |
| Given ERC20 token address not redeemable |
| Given ERC721Id instance not redeemable |
| Bonding opeation exceeded reserve's bondng limit for given ERC20 token address |
| Redeem operation exceeded reserve's redeem limit for given ERC20 token address |
| Reserve's balance for given ERC20 token address no sufficient |
| Reserve's minimum backing limit exceeded |
| Reserve received invalid oracle response |
The Reserve token 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.
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.
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.
To implement the vesting periods define by the Kolektivo multi-sig in the Reserve, a vesting contract 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.
Code | Description |
---|---|
| Invalid token recipient |
| Invalid token amount |
| Function is only callable by |
The BalancerV2Proxy.sol
contract is a custom contract meant to implement kCUR's price ceiling and floor mechanisms.
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.
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.
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 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.
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.
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 described in the Back-End Services section below.
Two oracles are necessary for the good functionment of the Reserve module: a cUSD/Celo oracle, and a kCUR 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 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.
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 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.
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.
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.
The service pulls the asset data from Coingecko.
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.
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.
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.
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.
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.
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.