Skip to content

Commit

Permalink
docs(epopoch-manager): add missing docummentation to structs and enum…
Browse files Browse the repository at this point in the history
… defitions (#362)
  • Loading branch information
kerber0x authored May 23, 2024
1 parent 4210f60 commit 31eb771
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 137 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ The Incentive Manager depends on the Epoch Manager, as incentives are distribute

### Bonding Manager

The Bonding Manager is the contract that manages the bonding in the protocol. It is responsible for bonding eligible tokens
and distributing the fees generated by the pools and vaults among the users that bond tokens. The Bonding Manager depends
The Bonding Manager is the contract that manages the bonding in the protocol. It is responsible for bonding eligible tokens
and distributing the fees generated by the pools and vaults among the users that bond tokens. The Bonding Manager depends
on the Epoch Manager, as the rewards distribution is done based on epochs.

### Epoch Manager
Expand Down
10 changes: 5 additions & 5 deletions contracts/liquidity_hub/bonding-manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ functionality so a regular user can understand how to interact with it.

### Rewards

Users must bond WHALE LSDs to the Bonding Manager to start earning rewards generated by the system, i.e. pools and vaults.
Every time there's a swap on the pool manager or a flashloan taken on the vault manager, a fee is collected and sent to
the Bonding Manager via the `FillRewards` message. The rewards collected within an epoch are temporarily stored in the
`UPCOMING_REWARD_BUCKET`, which is then distributed to bonders when the next epoch is created via the Epoch Manager
Users must bond WHALE LSDs to the Bonding Manager to start earning rewards generated by the system, i.e. pools and vaults.
Every time there's a swap on the pool manager or a flashloan taken on the vault manager, a fee is collected and sent to
the Bonding Manager via the `FillRewards` message. The rewards collected within an epoch are temporarily stored in the
`UPCOMING_REWARD_BUCKET`, which is then distributed to bonders when the next epoch is created via the Epoch Manager
contract, which has a hook to the Bonding Manager calling `EpochChangedHook`.

When `EpochChangedHook` is called, a new `RewardBucket` is created from the rewards collected in the previous epoch
Expand All @@ -28,7 +28,7 @@ claim takes place.
---
title: Bonding Manager Reward Distribution
---
flowchart
flowchart
P[Pool Manager] -->|FillRewards| B[Bonding Manager]
V[Vault Manager] -->|FillRewards| B
E[Epoch Manager] ==>|on_epoch_created| B
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@
"type": "string"
},
"Epoch": {
"description": "The epoch definition.",
"type": "object",
"required": [
"id",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@
"type": "string"
},
"Epoch": {
"description": "The epoch definition.",
"type": "object",
"required": [
"id",
Expand Down
18 changes: 9 additions & 9 deletions contracts/liquidity_hub/epoch-manager/README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
# Epoch Manager

The Epoch Manager is a contract which sole purpose is to create epochs on the Migaloo ecosystem, acting like a clock for
the other contracts.
The Epoch Manager is a contract which sole purpose is to create epochs on the Migaloo ecosystem, acting like a clock for
the other contracts.

An `Epoch` is a period of time that is defined by the `duration` parameter on `EpochConfig`, and they are used by other
An `Epoch` is a period of time that is defined by the `duration` parameter on `EpochConfig`, and they are used by other
contracts to take timely actions. For example, the Bonding Manager uses epochs to calculate the rewards for the bonders,
while the Incentive Manager uses epochs to calculate the incentive rewards for its users.

## How it works

The epoch configuration is set up when the contract is instantiated. The epoch configuration defines
The epoch configuration is set up when the contract is instantiated. The epoch configuration defines
the duration of an epoch and when the genesis epoch is gonna take place, i.e. the first epoch.

Once the genesis epoch is created, after the epoch duration has passed, anyone can create a new epoch by calling the
`CreateEpoch` message. This action will create a new epoch by increasing the epoch id by one, adjust the start time for
Once the genesis epoch is created, after the epoch duration has passed, anyone can create a new epoch by calling the
`CreateEpoch` message. This action will create a new epoch by increasing the epoch id by one, adjust the start time for
the new epoch and alert the contracts that have registered for the hook.

## Epoch Hook

There are two actions that only the owner of the Epoch Manager can execute: `AddHook` and `RemoveHook`. These add or
There are two actions that only the owner of the Epoch Manager can execute: `AddHook` and `RemoveHook`. These add or
remove a contract to the `HOOKS` list.

These contracts must implement the `EpochChangedHookMsg` interface, which is the signature of the message that will be
These contracts must implement the `EpochChangedHookMsg` interface, which is the signature of the message that will be
executed on the hooks when a new epoch is created. The hook contains the current `Epoch`, specifying the id and start_time.

```mermaid
Expand All @@ -34,4 +34,4 @@ E -.->|CreateEpoch| E
E -->|on_epoch_created| C2[Contract 2]
E -->|on_epoch_created| N[...]
E -->|on_epoch_created| CN[Contract N]
```
```
6 changes: 3 additions & 3 deletions contracts/liquidity_hub/epoch-manager/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ pub fn execute(
#[entry_point]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::Config {} => Ok(to_json_binary(&queries::query_config(deps)?)?),
QueryMsg::CurrentEpoch {} => Ok(to_json_binary(&queries::query_current_epoch(deps)?)?),
QueryMsg::Config => Ok(to_json_binary(&queries::query_config(deps)?)?),
QueryMsg::CurrentEpoch => Ok(to_json_binary(&queries::query_current_epoch(deps)?)?),
QueryMsg::Epoch { id } => Ok(to_json_binary(&queries::query_epoch(deps, id)?)?),
QueryMsg::Hooks {} => Ok(to_json_binary(&queries::query_hooks(deps)?)?),
QueryMsg::Hooks => Ok(to_json_binary(&queries::query_hooks(deps)?)?),
QueryMsg::Hook { hook } => Ok(to_json_binary(&queries::query_hook(deps, hook)?)?),
}
}
Expand Down
57 changes: 28 additions & 29 deletions contracts/liquidity_hub/incentive-manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,58 +5,57 @@ the incentives-related logic.

## How it works

The Incentives system is now completely encapsulated within one contract called the Incentive Manager. The Incentive
Manager has two main concepts; an `Incentive`, defined as a reward to be distributed and a `Position`, defined as a
The Incentives system is now completely encapsulated within one contract called the Incentive Manager. The Incentive
Manager has two main concepts; an `Incentive`, defined as a reward to be distributed and a `Position`, defined as a
user's liquidity in a pool locked in the contract.

Users of the Liquidity Hub, when providing liquidity, can opt to lock their LP shares which will in turn send them to
Users of the Liquidity Hub, when providing liquidity, can opt to lock their LP shares which will in turn send them to
the Incentive Manager until they are unlocked.

### Incentives

Creating incentives is permissionless, and incentives can be perpetual. This means they can be expanded forever. Anyone
can create an incentive by calling the `ManageIncentive` message with the `IncentiveAction::Fill` action and paying the
incentive creation fee, which is sent to the Bonding Manager.
can create an incentive by calling the `ManageIncentive` message with the `IncentiveAction::Fill` action and paying the
incentive creation fee, which is sent to the Bonding Manager.

Users can decide to provide an identifier, which they can later use to top up or close the incentive. If no identifier is
provided, the contract will generate one.

#### Topping up an Incentive

To top up an incentive, the owner of the incentive must call `ManageIncentive` with the `IncentiveAction::Fill` action.
The user must provide the same identifier as the original incentive. The incentive can only be topped up with the same
To top up an incentive, the owner of the incentive must call `ManageIncentive` with the `IncentiveAction::Fill` action.
The user must provide the same identifier as the original incentive. The incentive can only be topped up with the same
token as the original incentive, and the amount must be a multiple of the original incentive's amount.

#### Closing an Incentive

To close an incentive, the owner of the incentive or the owner of the contract must call `ManageIncentive` with the
To close an incentive, the owner of the incentive or the owner of the contract must call `ManageIncentive` with the
`IncentiveAction::Close` action with the identifier of the incentive to be closed. The incentive will be closed, and the
remaining tokens will be sent to the owner of the incentive.

#### Reward Distribution

Incentive rewards are distributed every epoch, which is created by the Epoch Manager. Whenever an epoch is created; the
Incentive Manager gets called via the `EpochChangedHook` hook, alerting the contract that a new epoch has been created.
The contract will then take snapshots for every LP token in the contract and save it in the `LP_WEIGHT_HISTORY` map for
Incentive rewards are distributed every epoch, which is created by the Epoch Manager. Whenever an epoch is created; the
Incentive Manager gets called via the `EpochChangedHook` hook, alerting the contract that a new epoch has been created.
The contract will then take snapshots for every LP token in the contract and save it in the `LP_WEIGHT_HISTORY` map for
the current epoch. That helps to calculate the rewards when users claim them.

The maximum number of concurrent incentives for a given LP denom is defined when the contract is instantiated, and it is
stored in the config as `max_concurrent_incentives`.


### Positions

Positions can be created, expanded (topped up), or withdrawn. This is done via the `ManagePosition`
Positions can be created, expanded (topped up), or withdrawn. This is done via the `ManagePosition`
message, followed by the desired action, i.e. `PositionAction::Fill`, `PositionAction::Close` or `PositionAction::Withdraw`.
When a user creates a position, it must provide an unlocking duration. The unlocking duration is the time it takes in
When a user creates a position, it must provide an unlocking duration. The unlocking duration is the time it takes in
seconds to unlock the position, which is necessary to withdraw the LP tokens from the contract.

#### Topping up a Position

When a user creates a position, the LP tokens are locked in the contract. The user can't withdraw them until the unlocking
duration is complete. To expand a position, the user must call `ManagePosition` with the `PositionAction::Fill` action
When a user creates a position, the LP tokens are locked in the contract. The user can't withdraw them until the unlocking
duration is complete. To expand a position, the user must call `ManagePosition` with the `PositionAction::Fill` action
using the same position identifier as the original position. In this case, since it's considered to be the same position,
any changes in the unlocking duration parameter passed along with the `PositionAction::Fill` action will be ignored.
any changes in the unlocking duration parameter passed along with the `PositionAction::Fill` action will be ignored.
Instead, the one in the original position will be used.

If a user doesn't provide an identifier when creating a position, the contract will generate one.
Expand All @@ -65,29 +64,29 @@ The minimum unlocking duration is 1 day, and the maximum is 365 days.

#### Closing a Position

Closing a position is done by calling `ManagePosition` with the `PositionAction::Close` action. The user must provide the
identifier of the position to be closed. Once this action is triggered, the `Position.open` state is set to false, and
Closing a position is done by calling `ManagePosition` with the `PositionAction::Close` action. The user must provide the
identifier of the position to be closed. Once this action is triggered, the `Position.open` state is set to false, and
`expiring_at` is set to the block height after which the position will be able to be withdrawn.

#### Withdrawing a Position

Once the unlocking duration is complete, the user can withdraw the LP tokens from the contract by calling the `ManagePosition`
with the `PositionAction::Withdraw` action. Alternatively, if the user doesn't want to wait for the unlocking duration to
complete, it is possible to do an emergency withdrawal by passing `true` on the `emergency_unlock` parameter. This will
unlock and withdraw the position immediately, but the user will pay a penalty fee that will go the Bonding Manager and
Once the unlocking duration is complete, the user can withdraw the LP tokens from the contract by calling the `ManagePosition`
with the `PositionAction::Withdraw` action. Alternatively, if the user doesn't want to wait for the unlocking duration to
complete, it is possible to do an emergency withdrawal by passing `true` on the `emergency_unlock` parameter. This will
unlock and withdraw the position immediately, but the user will pay a penalty fee that will go the Bonding Manager and
distributed to the bonders.

Once the user closes and withdraws the position, they receive their LP tokens back.

### Claiming Incentive Rewards

Users can claim incentive rewards from active incentives for their LP tokens, only if they have a position in the
contract. Users can only claim rewards for future epochs, i.e. after the epoch in which the position was created.
Users can claim incentive rewards from active incentives for their LP tokens, only if they have a position in the
contract. Users can only claim rewards for future epochs, i.e. after the epoch in which the position was created.

Incentive rewards are distributed based on the user's share of the total LP tokens in the contract. So if there's a total
of 100 LP tokens in the contract, and a user has 10 LP tokens, the user will receive 10% of the rewards for that epoch,
Incentive rewards are distributed based on the user's share of the total LP tokens in the contract. So if there's a total
of 100 LP tokens in the contract, and a user has 10 LP tokens, the user will receive 10% of the rewards for that epoch,
for that given incentive.

To claim rewards, the user must call the `Claim` message. Once that's done, the contract will save the epoch in which the
claim was made in `LAST_CLAIMED_EPOCH`, and will sync the user's LP weight history saved in `LP_WEIGHT_HISTORY`. This helps
To claim rewards, the user must call the `Claim` message. Once that's done, the contract will save the epoch in which the
claim was made in `LAST_CLAIMED_EPOCH`, and will sync the user's LP weight history saved in `LP_WEIGHT_HISTORY`. This helps
computing the rewards for the user.
34 changes: 17 additions & 17 deletions contracts/liquidity_hub/pool-manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,43 +15,43 @@ functionality, so a regular user can understand how to interact with it.

Creating pools is a simple and permissionless process. A user can call the `CreatePool` message, with the desired pool
parameters such as asset denoms, fees, and pool type among others, together with the pool creation fee. The pool creation
fee is a protocol fee that is sent to the Bonding Manager via the `FillRewards` message. There can be multiple pools
for the same asset pair, though each pool must have a unique identifier. Pools cannot be removed or updated once
fee is a protocol fee that is sent to the Bonding Manager via the `FillRewards` message. There can be multiple pools
for the same asset pair, though each pool must have a unique identifier. Pools cannot be removed or updated once
created, so it is important to get the parameters right from the start.

The liquidity in a given pool is tracked with LP tokens, which are minted via the Token Factory module by the Pool Manager.
The liquidity in a given pool is tracked with LP tokens, which are minted via the Token Factory module by the Pool Manager.
These tokens represent the user's share of a pool's liquidity, and they can be used to redeem the assets in the pool.

Pool information is stored in the `POOLS` map, containing information such as the asset denoms and decimals, the LP denom,
Pool information is stored in the `POOLS` map, containing information such as the asset denoms and decimals, the LP denom,
the assets in the pool (balance), the pool type and pool fees.

A pool can be of two types: `ConstantProduct` (xyk) or `StableSwap`. The `ConstantProduct` type is suitable for assets that
may have varying values and are not intended to be equivalent. The `StableSwap` type is suitable for assets that are
A pool can be of two types: `ConstantProduct` (xyk) or `StableSwap`. The `ConstantProduct` type is suitable for assets that
may have varying values and are not intended to be equivalent. The `StableSwap` type is suitable for assets that are
meant to be the same and whose values should be approximately the same, such as stablecoins.

### Deposits and Withdrawals

Users can deposit and withdraw assets from the pools at any time. To deposit, users must call the `ProvideLiquidity`
message, together with the pool identifier and the assets to deposit among other parameters. For pools with two assets,
it is possible to provide liquidity with a single asset. The Pool Manager will swap half of the provided asset for the
Users can deposit and withdraw assets from the pools at any time. To deposit, users must call the `ProvideLiquidity`
message, together with the pool identifier and the assets to deposit among other parameters. For pools with two assets,
it is possible to provide liquidity with a single asset. The Pool Manager will swap half of the provided asset for the
other asset in the pool, ensuring the pool's balance is kept in check.

Once the user has provided liquidity, they will receive LP tokens in return proportional to the amount of liquidity
Once the user has provided liquidity, they will receive LP tokens in return proportional to the amount of liquidity
provided.

To withdraw liquidity, users must call the `WithdrawLiquidity` message, with the pool identifier together with the LP
token to redeem the assets. The Pool Manager will burn the LP tokens and send the corresponding assets to the user,
To withdraw liquidity, users must call the `WithdrawLiquidity` message, with the pool identifier together with the LP
token to redeem the assets. The Pool Manager will burn the LP tokens and send the corresponding assets to the user,
updating the pool's balance accordingly.

### Swaps

Swaps are the main feature of the Pool Manager. Users can swap assets from one pool to another by using the `Swap` message.
If the swap is a single-hop operation, the Pool Manager will perform the swap directly. If the swap is a multi-hop operation,
the `ExecuteSwapOperations` message should be used instead, providing the route to follow for the swap to be executed
successfully.
If the swap is a single-hop operation, the Pool Manager will perform the swap directly. If the swap is a multi-hop operation,
the `ExecuteSwapOperations` message should be used instead, providing the route to follow for the swap to be executed
successfully.

After a swap takes place, the pool's balances are updated, and the fees are collected. The Bonding Manager receives the
protocol fee via the `FillRewards` message, while the swap fee remains in the pool to benefit the LP token holders,
After a swap takes place, the pool's balances are updated, and the fees are collected. The Bonding Manager receives the
protocol fee via the `FillRewards` message, while the swap fee remains in the pool to benefit the LP token holders,
increasing the pool's liquidity and thus the LP token value.

On Osmosis, there's an additional fee that is sent to the Osmosis community pool.
Loading

0 comments on commit 31eb771

Please sign in to comment.