Skip to content

Commit

Permalink
Policy 2 (OlympusDAO#52)
Browse files Browse the repository at this point in the history
* update intro

* update bonds & inverse bonds

* update staking & add equation

* sidebar positions dont matter

* add bophades

* update treasury & pol

* governance updates

* update favicon

* update meta tag
  • Loading branch information
appleseed-iii authored Nov 17, 2022
1 parent 946ad34 commit 8e46df2
Showing 15 changed files with 155 additions and 118 deletions.
12 changes: 6 additions & 6 deletions docs/basics/bonding.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
---
sidebar_position: 3
sidebar_position: 1
---

# Bonds

Olympus bonds are a financial primitive for protocols to acquire assets, including their own liquidity, over a specified time in exchange for tokens upon maturity. In other words, Olympus bonds are a pricing mechanism for any two ERC-20 tokens that does not rely on third parties like oracles.
Olympus bonds are a financial primitive that allow transacting assets,often between a protocol and individual stakeholders,over a specified time-period and at completely market-driven prices. In other words, Olympus bonds are a market-driven pricing mechanism for any two ERC-20 tokens that does not rely on third parties like oracles.

External Bonds are an application of this primitive, which sells OHM at a discount to acquire Treasury assets. External Bonds represent the primary mechanism for Olympus Treasury inflows.
Reserve Bonds are an application of this primitive, which sells OHM at a discount to acquire Treasury assets. External Bonds represent the primary mechanism for Olympus Treasury inflows.

When purchasing a bond, purchasers commit a capital sum upfront in return for OHM upon maturity. Thus, a bond’s profit is uncertain and dependent on the price of OHM at the time of maturity.
When purchasing a bond, purchasers commit a capital sum upfront in return for OHM upon maturity. Thus, a bond’s profit is uncertain and dependent on the price of OHM at the time of maturity.

When viewing a current bond offering, a positive discount indicates that the bond is currently offering OHM at a discount to its current market price. A negative discount indicates that the bond is currently offering OHM at a premium to its current market price.
When viewing a current bond offering, a positive discount indicates that the bond is currently offering OHM at a discount to its current market price. A negative discount indicates that the bond is currently offering OHM at a premium to its current market price.

This variable discount rate is how a bond market internally governs its supply by responding to demand. This ensures that a bond market’s supply is sold over the specified period of time.
This variable discount rate is how a bond market internally governs its supply by responding to demand. This ensures that a bond market’s supply is sold over the specified period of time.
107 changes: 104 additions & 3 deletions docs/basics/bophades.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,108 @@
---
sidebar_position: 4
sidebar_position: 1
sidebar_label: "Bophades / Default"
---

# Bophades / Default
# A Design Pattern for Better Protocol Development

Default framework explanation
Today, most projects take a process-centric approach towards protocol development: each smart contract is developed to manage a process along a chain of logic that is triggered when external interactions occur.

This is generally the most intuitive approach because it’s how our brain thinks when designing systems: one step in logic at a time. However, there’s an inherent issue in building a protocol this way. Over time, as the protocol evolves, more “steps in logic” are added across the system, creating long and convoluted chains of processes that look like this:

![[MakerDAO’s protocol architecture.](https://docs.makerdao.com/)](/gitbook/assets/default-maker-dao.png)

[MakerDAO’s protocol architecture.](https://docs.makerdao.com/)

or this:

![[Aave’s protocol architecture.](https://docs.aave.com/developers/v/2.0/the-core-protocol/protocol-overview)](/gitbook/assets/default-aave.png)

[Aave’s protocol architecture.](https://docs.aave.com/developers/v/2.0/the-core-protocol/protocol-overview)

When protocols are architected in these “web-like” structures, they can be difficult to understand, as they break a simple interaction into multiple layers of abstract logic. When contracts are developed this way, it’s difficult to track down where the calls are coming from or going to—it’s easy to get lost in the web of logic. This puts a huge burden on a user trying to understand the system, often requiring them to read an excessive amount of documentation just to figure out what’s going on behind the scenes.

This pattern can be frustrating to deal with, and discouraging developers from contributing to the existing codebase or integrating with the protocol. And when they do, it increases the potential for bugs and unintended behavior to occur.

---

The core philosophy of Default is to shift the focus of writing contracts away from organizing contracts around processes, and towards organizing contracts around data models. In particular, what data models exist as protocol dependencies, and how they can be modified.

The goal is to turn a protocol from looking something like this:

![before-default](/gitbook/assets/before-default.png)

into something look like this:

![after-default](/gitbook/assets/after-default.png)

With a consistent contract architecture, developers can make certain assumptions around the intended behavior for any given contract in the protocol even if they are unfamiliar with the code. This model also limits the maximum depth of dependencies to a single contract, removing the potential for long or circular dependency chains to form.

The idea to separate data and business logic isn’t novel; it just hasn’t been applied to smart contract development yet. Default is inspired by existing design patterns in other areas of computing that are more mature, like computer operating systems and web development.

# The Default Framework

---

In Default, contracts are either Modules or Policies, which are essentially the “front-end” and “back-end” of a protocol: Modules are the back-end, and Policies are the front-end.

Modules are **internal-facing contracts** that store shared state across the protocol. You can think of them as microservices: each Module is responsible for managing a particular data model within the larger system. Modules can only be accessed through whitelisted Policy contracts, and have no dependencies of their own. Modules can only modify their own internal state.

Policies are **external-facing contracts** that receive inbound calls to the protocol, and routes all the necessary updates to data models via Modules. Policies effectively act as intermediaries between external interactions and internal state changes, creating a buffer where all protocol business logic is composed.

While modules describe *what* data models exist within the protocol and *how* they can be modified, policy contracts contain the context for *why* those changes happen. This separation of *what* and *why* in the protocol allows for greater flexibility in design while retaining some properties of immutability, which dramatically simplifies protocol development.

---

One example of a module could be an ERC20 token: ERC20 contracts define a self-contained data model around token account balances (i.e. `balanceOf`). The `transfer()`, `mint()`, and `burn()` functions define how account balances can be changed, while the `totalSupply()` function provides useful metadata about balances, such as the aggregate amount of balances in existence.

Notice that changes in an ERC20 contract are limited to its internal state: nothing happens outside the contract when account balances are modified. This makes ERC20’s generic enough to be applicable for a wide variety of use cases, like managing vault deposits, facilitating token swaps, or distributing mining rewards for a protocol.

There is an interesting case about this example: Module functions should not be called by any contracts except Policies. However, users should be able to interact directly with the ERC20 via transfer(). How is this case handled?

The ultimate distinction lies in *permissioned* versus *permissionless* state changes. When a contract needs to enforce certain permissionless guarantees, those functions should be atomic in the contract and called directly by the user. Default is mostly applicable to permissioned functions, like `mint()` and `burn()`. Interesting cases like `transferFrom()` emerge—should external integrations be permissioned or permissionless? This is up to the protocol to decide.

## Protocol Organization and Upgradability

Default views the entire contract set as a cohesive unit: rather than upgrading an individual contract’s code, it’s better to just upgrade the protocol’s *contract set.* In Default, there is a special contract registry that manages the contract set called the Kernel. This means that all changes to the protocol are made within in a single contract, unifying the model of upgradability.

In this paradigm, each contract in the protocol remains immutable, but the set of contracts that make up a protocol can change. This makes Default incredibly easy to work with; developers only need to understand a single contract—the Kernel—before they can begin building a protocol using the framework.

### Kernel.sol

There are a limited number of actions that the Kernel can take to update the protocol. These actions are:

**1. Approving a policy**

**2. Terminating a policy**

**3. Installing a module**

**4. Upgrading a module**

Each of these actions is executed on a “target”, which is the address of the contract on which the action is being performed. This combination of an action and a target is submitted as an “instruction” in the Kernel: approve 0xc199e... as a Policy, install 0x410f... as a Module, etc.

Policies are a*pproved* or *terminated* via simple whitelist in the Kernel. The whitelist is represented as a mapping of contract addresses to a boolean that represents whether that policy is authorized to interact with modules. Once a policy is terminated, it is no longer authorized to call modules, effectively deprecating the feature.

Modules can be *installed* or *upgraded* with a directory in the Kernel. Each module is mapping their address to a three letter keycode in the Kernel, which is used to reference the underlying data model of the module from within Policies. For example, a token module might have the keycode “TOKEN”, while a treasury module might have the keycode “TRSRY”. Once installed, a module cannot be removed, only upgraded.

This to ensure some backwards compatibility for contract dependencies in Policy contracts: once a keycode is mapped to a module in the Kernel, it will always point to an existing data model. Keycodes are three letters to discourage module bloat as well as reduce potential confusion around dependency names.

---

### The Executor

In the Kernel.sol contract code, there’s one action that hasn’t been discussed: changing the executor. In the Kernel, the executor is the address with the permission to execute instructions—you can think of the executor as the “owner” of the Kernel contract.

The initial “executor” is the deployer of a Kernel contract, but can be changed to another address to include possibilities for on-chain governance via `changeExecutor()`. For convenience, Default has an optional module that can be installed in any Kernel called “GPU”, which enables a protocol to execute multiple instructions in the same transaction, simplifying multi-contract migrations.

---

By defining all the protocol changes in a single contract, Default is a very lightweight and simple framework to adopt. Developers only need to understand how the Kernel works before building any type of protocol on top: whether they are DeFi protocols, NFT marketplaces, or DAO tooling.

You can view a sample template for a Default protocol here:

[GitHub - fullyallocated/Default: Protocol Development & Upgradability Framework](https://github.com/fullyallocated/Default)

### What’s Next?

Default is still an emerging standard. If you are interested in providing feedback or using it to build your protocol, please [reach out on Twitter](http://Twitter.com/fullyallocated). We’d love to hear your thoughts and ideas.
96 changes: 3 additions & 93 deletions docs/basics/inverse-bonds.md
Original file line number Diff line number Diff line change
@@ -7,97 +7,9 @@ sidebar_label: Inverse Bonds

## What are inverse bonds?

Inverse bonds have been introduced as a protocol lever in [OIP-76](https://snapshot.org/#/olympusdao.eth/proposal/0xa544837835f3c4e681efba18d33623d4eb2acedec352dfc3c926a45902cd3612)
as a way to support the price of OHM when it is below the backing per OHM. As their name suggests,
one can think of inverse bonds as doing the "inverse" of what a regular bond does:
instead of taking a treasury asset in exchange for OHM, **it takes in OHM in exchange for an asset from the treasury**.
As their name suggests, one can think of inverse bonds as doing the "inverse" of what a regular bond does: instead of taking a treasury asset in exchange for OHM, **it takes in OHM in exchange for an asset from the treasury**. Inverse bonds have been introduced as a protocol lever in [OIP-76](https://snapshot.org/#/olympusdao.eth/proposal/0xa544837835f3c4e681efba18d33623d4eb2acedec352dfc3c926a45902cd3612) as a way to support the price of OHM when it is below the (liquid) backing per OHM, and with the launch of RBS, they’ve become an integral part of Olympus’ monetary policy.

Here is a TL;DR on inverse bonds:
- They buy your OHM in exchange for a backing asset from the treasury.
- They buy your OHM at a premium (slightly above market price) and then burn it.
- They buy your OHM at a slight discount to the backing per OHM, increasing the backing per remaining OHM.
- They have no vesting, meaning that the asset exchange is instant.
- They are only available while the OHM market price is below the backing per OHM.
- They are launched by the policy team.
- Their price is determined by the market.

## Why are these bonds being introduced?

The purpose of inverse bonds is to absorb some sell pressure for OHM, supporting OHM price while bringing in revenues and
increasing the backing per OHM.

## What assets can I bond?

- You can bond only OHM v2.
- You must unstake your sOHM or gOHM first.

## How much will these bonds cost?

- Their pricing mechanic is basically the same as for regular bonds:
- The price and payout value of an inverse bond start at the market price of OHM.
- The payout amount (premium) slowly increases until someone buys a bond.
- The payout amount (premium) is then reduced and will slowly increase again.
- They will effectively buy OHM at a premium – slightly above market price.
- You will get more value for your OHM compared to selling directly to the market.

## What asset will I get for these bonds?

- Different bonds will be provided that pay out different assets.
- The policy team will add and remove bonds based on market conditions and treasury composition.

## How many of these bonds will be available?

- Bonds have a limited capacity and are sold out once their capacity is reached.
- While the policy team is ultimately responsible for implementing inverse bonds, the lower the price of OHM compared to backing, the more capacity should be expected.

## When will these bonds become available?

- The [Snapshot governance vote](https://snapshot.org/#/olympusdao.eth/proposal/0xa544837835f3c4e681efba18d33623d4eb2acedec352dfc3c926a45902cd3612) has passed and inverse bonds can now be used as a protocol lever.
- The policy team is responsible for their implementation, notably the timing of inverse bonds and their capacities.

## Where can I buy these bonds?

- You will be able to buy them on the [Olympus website](https://app.olympusdao.finance) but only on the Ethereum network.
- They will be offered only while OHM trades below the backing per OHM.

## How do these bonds affect the backing per OHM?

- The protocol acquires and burns OHM at a discount compared to backing per OHM.
- The revenues from inverse bonds increase the backing of all remaining OHM tokens.

## Do these bonds guarantee a price floor?

- No. They simply increase the backing per OHM and absorb some sell pressure.
- It is effectively the treasury acting as a whale buying OHM, supporting the market.
As this whale can effectively buy all the circulating OHM, it should give the market more confidence.

## Can these bonds drain the treasury?

- The policy team decides how much OHM can be bonded in total.
- The policy team allocates the amount of payout assets upfront to safeguard the treasury.
- In terms of implementation, inverse bonds will not have direct access to the full treasury assets.

## Will the DAO itself bond OHM?

- No, OHM in DAO funds will not be used for inverse bonds.

## Are these bonds the same as a buyback?

While they seem similar there are notable differences:

- They absorb sell pressure because they buy OHM slightly above the market price.
- They reduce sell pressure further because they increase the backing per OHM.
- Their availability is limited to certain market conditions.
- The amount of OHM tokens that the protocol will acquire and burn is limited.
- Sales are driven by market demand and not by the protocol or the DAO, removing moral hazard.

## What is the backing per OHM?

- The USD value of the assets in the treasury is called “backing” or “reserves”.
- OHM in liquidity pairs does not count towards the backing.
- Locked assets like vlCVX and veFXS do not count towards the backing (for this purpose).
- That backing divided by the amount of OHM in circulation is the “backing per OHM”.
- The current backing can be found on the [Olympus dashboard](https://app.olympusdao.finance/#/dashboard) under “Liquid backing per OHM”.
Unlike reserve bonds, they vest instantly, and are the core mechanism of absorbing sell pressure from the market.

## Example

@@ -107,6 +19,4 @@ While they seem similar there are notable differences:
- `$100` bond price
- `$105` payout per bond (`5%` premium over the market price of OHM)

→ Treasury takes in `$100 in OHM` in exchange for `$105 in ETH`, supporting the market by removing some sell pressure.
→ That `OHM` is burnt.
→ The treasury pockets a revenue of `$15`, increasing the backing of the remaining OHM tokens.
Here, the treasury receives $10 worth of OHM and delivers the user $10.50 worth of ETH.The backing per OHM also increases in that scenario, benefitting all remaining OHM holders.
Loading

0 comments on commit 8e46df2

Please sign in to comment.