update spec, add money market deprecation steps (#841)

This commit is contained in:
Denali Marsh 2021-02-22 21:52:17 +01:00 committed by GitHub
parent 1499a89ce5
commit 99fb79a1ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 112 additions and 129 deletions

View File

@ -4,7 +4,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
) )
// BeginBlocker updates interest rates and attempts liquidations // BeginBlocker updates interest rates
func BeginBlocker(ctx sdk.Context, k Keeper) { func BeginBlocker(ctx sdk.Context, k Keeper) {
k.ApplyInterestRateUpdates(ctx) k.ApplyInterestRateUpdates(ctx)
} }

View File

@ -8,7 +8,6 @@ import (
) )
const ( const (
AttributeKeyBlockHeight = types.AttributeKeyBlockHeight
AttributeKeyBorrow = types.AttributeKeyBorrow AttributeKeyBorrow = types.AttributeKeyBorrow
AttributeKeyBorrowCoins = types.AttributeKeyBorrowCoins AttributeKeyBorrowCoins = types.AttributeKeyBorrowCoins
AttributeKeyBorrower = types.AttributeKeyBorrower AttributeKeyBorrower = types.AttributeKeyBorrower
@ -17,16 +16,12 @@ const (
AttributeKeyDepositDenom = types.AttributeKeyDepositDenom AttributeKeyDepositDenom = types.AttributeKeyDepositDenom
AttributeKeyDepositor = types.AttributeKeyDepositor AttributeKeyDepositor = types.AttributeKeyDepositor
AttributeKeyRepayCoins = types.AttributeKeyRepayCoins AttributeKeyRepayCoins = types.AttributeKeyRepayCoins
AttributeKeyRewardsDistribution = types.AttributeKeyRewardsDistribution
AttributeKeySender = types.AttributeKeySender AttributeKeySender = types.AttributeKeySender
AttributeValueCategory = types.AttributeValueCategory AttributeValueCategory = types.AttributeValueCategory
DefaultParamspace = types.DefaultParamspace DefaultParamspace = types.DefaultParamspace
EventTypeDeleteHardDeposit = types.EventTypeDeleteHardDeposit
EventTypeHardLiquidation = types.EventTypeHardLiquidation EventTypeHardLiquidation = types.EventTypeHardLiquidation
EventTypeHardBorrow = types.EventTypeHardBorrow EventTypeHardBorrow = types.EventTypeHardBorrow
EventTypeHardDelegatorDistribution = types.EventTypeHardDelegatorDistribution
EventTypeHardDeposit = types.EventTypeHardDeposit EventTypeHardDeposit = types.EventTypeHardDeposit
EventTypeHardLPDistribution = types.EventTypeHardLPDistribution
EventTypeHardRepay = types.EventTypeHardRepay EventTypeHardRepay = types.EventTypeHardRepay
EventTypeHardWithdrawal = types.EventTypeHardWithdrawal EventTypeHardWithdrawal = types.EventTypeHardWithdrawal
ModuleAccountName = types.ModuleAccountName ModuleAccountName = types.ModuleAccountName

View File

@ -6,9 +6,8 @@ order: 1
## Automated, Cross-Chain Money Markets ## Automated, Cross-Chain Money Markets
The hard module provides for functionality and governance of a two-sided money market protocol with autonomous interest rates and partially autonomous liquidations. The main state transitions in the hard module are composed of deposit, withdraw, borrow and repay actions. Additionally, borrow positions can be liquidated by the autonomous liquidation engine or by an external party called a "keeper". Keepers receive a fee in exchange for liquidating risk positions, and the fee rate is determined by governance. Internally, all funds are stored in a module account (the cosmos-sdk equivalent of the `address` portion of a smart contract), and can be accessed via the above actions. Each money market has governance parameters which are controlled by token-holder governance. Of particular note are the interest rate model, which determines (using a static formula) what the prevailing rate of interest will be for each block, and the loan-to-value (LTV), which determines how much borrowing power each unit of deposited collateral will count for. Initial parameterization of the hard module will stipulate that all markets are over-collateralized and that overall borrow limits for each collateral will start small and rise gradually. The hard module provides for functionality and governance of a two-sided money market protocol with autonomous interest rates. The main state transitions in the hard module are composed of deposit, withdraw, borrow and repay actions. Borrow positions can be liquidated by an external party called a "keeper". Keepers receive a fee in exchange for liquidating risk positions, and the fee rate is determined by governance. Internally, all funds are stored in a module account (the cosmos-sdk equivalent of the `address` portion of a smart contract), and can be accessed via the above actions. Each money market has governance parameters which are controlled by token-holder governance. Of particular note are the interest rate model, which determines (using a static formula) what the prevailing rate of interest will be for each block, and the loan-to-value (LTV), which determines how much borrowing power each unit of deposited collateral will count for. Initial parameterization of the hard module will stipulate that all markets are over-collateralized and that overall borrow limits for each collateral will start small and rise gradually.
## HARD Token distribution ## HARD Token distribution
[See Incentive Module](../../incentive/spec/01_concepts.md) [See Incentive Module](../../incentive/spec/01_concepts.md)

View File

@ -6,13 +6,19 @@ order: 2
## Parameters and Genesis State ## Parameters and Genesis State
`Parameters` define the governance parameters and default behavior of each money market. `Parameters` define the governance parameters and default behavior of each money market. **Money markets should not be removed from params without careful procedures** as it will disable withdraws and liquidations. To deprecate a money market, the following steps should be observed:
1. Borrowing: prevent new borrows by setting param MoneyMarket.BorrowLimit.MaximumLimit to 0.
2. Interest: turn off interest accumulation by setting params MoneyMarket.InterestRateModel.BaseRateAPY and MoneyMarket.InterestRateModel.Kink to 0.
3. Rewards: turn off supply side and/or borrow side rewards by removing any coins in the relevant RewardsPerSecond param in the Incentive module.
Without financial incentives, borrowers and suppliers will withdraw their funds from the money market over time. Once the balances have reached an acceptable level the money market can be deprecated and removed from params, with any additional lingering user funds reimbursed/reallocated as appropriate via a chain upgrade.
```go ```go
// Params governance parameters for hard module // Params governance parameters for hard module
type Params struct { type Params struct {
MoneyMarkets MoneyMarkets `json:"money_markets" yaml:"money_markets"` // defines the parameters for each money market MoneyMarkets MoneyMarkets `json:"money_markets" yaml:"money_markets"`
CheckLtvIndexCount int `json:"check_ltv_index_count" yaml:"check_ltv_index_count"` // defines the number of positions that are checked for liquidation at the beginning of each block MinimumBorrowUSDValue sdk.Dec `json:"minimum_borrow_usd_value" yaml:"minimum_borrow_usd_value"`
} }
// MoneyMarket is a money market for an individual asset // MoneyMarket is a money market for an individual asset
@ -23,7 +29,6 @@ type MoneyMarket struct {
ConversionFactor sdk.Int `json:"conversion_factor" yaml:"conversion_factor"` //the internal conversion factor for going from the smallest unit of a token to a whole unit (ie. 8 for BTC, 6 for KAVA, 18 for ETH) ConversionFactor sdk.Int `json:"conversion_factor" yaml:"conversion_factor"` //the internal conversion factor for going from the smallest unit of a token to a whole unit (ie. 8 for BTC, 6 for KAVA, 18 for ETH)
InterestRateModel InterestRateModel `json:"interest_rate_model" yaml:"interest_rate_model"` // the model that determines the prevailing interest rate at each block InterestRateModel InterestRateModel `json:"interest_rate_model" yaml:"interest_rate_model"` // the model that determines the prevailing interest rate at each block
ReserveFactor sdk.Dec `json:"reserve_factor" yaml:"reserve_factor"` // the percentage of interest that is accumulated by the protocol as reserves ReserveFactor sdk.Dec `json:"reserve_factor" yaml:"reserve_factor"` // the percentage of interest that is accumulated by the protocol as reserves
AuctionSize sdk.Int `json:"auction_size" yaml:"auction_size"` // the maximum size of auction for this money market. Liquidations larger than this will be broken down into multiple auctions
KeeperRewardPercentage sdk.Dec `json:"keeper_reward_percentage" yaml:"keeper_reward_percentages"` // the percentage of a liquidation that is given to the keeper that liquidated the position KeeperRewardPercentage sdk.Dec `json:"keeper_reward_percentage" yaml:"keeper_reward_percentages"` // the percentage of a liquidation that is given to the keeper that liquidated the position
} }

View File

@ -40,11 +40,12 @@ This message creates a `Borrow` object is one does not exist, or updates an exis
// MsgRepay repays funds to the hard module. // MsgRepay repays funds to the hard module.
type MsgRepay struct { type MsgRepay struct {
Sender sdk.AccAddress `json:"sender" yaml:"sender"` Sender sdk.AccAddress `json:"sender" yaml:"sender"`
Owner sdk.AccAddress `json:"owner" yaml:"owner"`
Amount sdk.Coins `json:"amount" yaml:"amount"` Amount sdk.Coins `json:"amount" yaml:"amount"`
} }
``` ```
This message decrements a `Borrow` object, or deletes one if the `Amount` specified is greater than or equal to the total borrowed amount, as well as creating/updating the necessary indexes and synchronizing any outstanding interest. For example, a message which requests to repay 100xyz tokens, if `Sender` has only deposited 50xyz tokens, will repay the full 50xyz tokens. The `Amount` of coins, or the current borrow amount, is transferred from `Sender`. The global variable for `TotalBorrowed` is updated. This message decrements a `Borrow` object, or deletes one if the `Amount` specified is greater than or equal to the total borrowed amount, as well as creating/updating the necessary indexes and synchronizing any outstanding interest. For example, a message which requests to repay 100xyz tokens, if `Owner` has only deposited 50xyz tokens, the `Sender` will repay the full 50xyz tokens. The `Amount` of coins, or the current borrow amount, is transferred from `Sender`. The global variable for `TotalBorrowed` is updated.
```go ```go
// MsgLiquidate attempts to liquidate a borrower's borrow // MsgLiquidate attempts to liquidate a borrower's borrow

View File

@ -20,7 +20,7 @@ The hard module emits the following events:
### MsgWithdraw ### MsgWithdraw
| Type | Attribute Key | Attribute Value | | Type | Attribute Key | Attribute Value |
| ------------------- | ------------- | --------------------- | | --------------- | ------------- | --------------------- |
| message | module | hard | | message | module | hard |
| message | sender | `{sender address}` | | message | sender | `{sender address}` |
| hard_withdrawal | amount | `{amount}` | | hard_withdrawal | amount | `{amount}` |
@ -29,28 +29,18 @@ The hard module emits the following events:
### MsgBorrow ### MsgBorrow
| Type | Attribute Key | Attribute Value | | Type | Attribute Key | Attribute Value |
| -------------- | ------------- | --------------------- | | --------------- | ------------- | -------------------- |
| message | module | hard | | message | module | hard |
| message | sender | `{sender address}` | | message | sender | `{sender address}` |
| hard_borrow | borrow_coins | `{amount}` | | hard_borrow | borrow_coins | `{amount}` |
| hard_withdrawal| borrower | `{borrower address}` | | hard_withdrawal | borrower | `{borrower address}` |
### MsgRepay ### MsgRepay
| Type | Attribute Key | Attribute Value | | Type | Attribute Key | Attribute Value |
| -------------- | ------------- | --------------------- | | ---------- | ------------- | -------------------- |
| message | module | hard | | message | module | hard |
| message | sender | `{sender address}` | | message | sender | `{sender address}` |
| message | owner | `{owner address}` |
| hard_repay | repay_coins | `{amount}` | | hard_repay | repay_coins | `{amount}` |
| hard_repay | sender | `{borrower address}` | | hard_repay | sender | `{borrower address}` |
## BeginBlock
| Type | Attribute Key | Attribute Value |
| --------------------------- | ------------------- | ----------------------- |
| hard_lp_distribution | block_height | `{block height}` |
| hard_lp_distribution | rewards_distributed | `{rewards distributed}` |
| hard_lp_distribution | deposit_denom | `{deposit denom}` |
| hard_delegator_distribution | block_height | `{block height}` |
| hard_delegator_distribution | rewards_distributed | `{rewards distributed}` |
| hard_delegator_distribution | deposit_denom | `{deposit denom}` |

View File

@ -4,39 +4,38 @@ order: 5
# Parameters # Parameters
The hard module has the following parameters: Example parameters for the Hard module:
| Key | Type | Example | Description | | Key | Type | Example | Description |
| ------------------------------ | ------------------------------------- | ------------- | ----------------------------------------------------------------------------| | --------------------- | ------------------- | ------------- | -------------------------------------------- |
| MoneyMarkets | array (MoneyMarket) | [{see below}] | array of params for each supported market | | MoneyMarkets | array (MoneyMarket) | [{see below}] | Array of params for each supported market |
| CheckLtvIndexCount | int | 6 | Number of borrow positions to check for liquidation in each begin blocker | | MinimumBorrowUSDValue | sdk.Dec | 10.0 | Minimum amount an individual user can borrow |
Each `MoneyMarket` has the following parameters Example parameters for `MoneyMarket`:
| Key | Type | Example | Description | | Key | Type | Example | Description |
| ------------------------- | ------------------ | ---------------------- | --------------------------------------------------------------------- | | ---------------------- | ----------------- | ------------- | --------------------------------------------------------------------- |
| Denom | string | "bnb" | coin denom of the asset which can be deposited and borrowed | | Denom | string | "bnb" | Coin denom of the asset which can be deposited and borrowed |
| BorrowLimit | BorrowLimit | [{see below}] | borrow limits applied to this money market | | BorrowLimit | BorrowLimit | [{see below}] | Borrow limits applied to this money market |
| SpotMarketID | string | "bnb:usd" | the market id which determines the price of the asset | | SpotMarketID | string | "bnb:usd" | The market id which determines the price of the asset |
| ConversionFactor | Int | "6" | conversion factor for one unit (ie BNB) to the smallest internal unit | | ConversionFactor | Int | "6" | Conversion factor for one unit (ie BNB) to the smallest internal unit |
| InterestRateModel | InterestRateModel | [{see below}] | Model which determines the prevailing interest rate per block | | InterestRateModel | InterestRateModel | [{see below}] | Model which determines the prevailing interest rate per block |
| ReserveFactor | Dec | "0.01" | Percentage of interest that is kept as protocol reserves | | ReserveFactor | Dec | "0.01" | Percentage of interest that is kept as protocol reserves |
| AuctionSize | Int | "1000000000" | The maximum size of an individual auction |
| KeeperRewardPercentage | Dec | "0.02" | Percentage of deposit rewarded to keeper who liquidates a position | | KeeperRewardPercentage | Dec | "0.02" | Percentage of deposit rewarded to keeper who liquidates a position |
Each `BorrowLimit` has the following parameters Example parameters for `BorrowLimit`:
| Key | Type | Example | Description | | Key | Type | Example | Description |
| --------------------- | ------------------ | ---------------------- | ------------------------------------------------------------------------ | | ------------ | ---- | ------------ | ----------------------------------------------------------------------- |
| HasMaxLimit | bool | "true" | boolean for if a maximum limit is in effect | | HasMaxLimit | bool | "true" | Boolean for if a maximum limit is in effect |
| MaximumLimit | Dec | "10000000.0" | global maximum amount of coins that can be borrowed | | MaximumLimit | Dec | "10000000.0" | Global maximum amount of coins that can be borrowed |
| LoanToValue | Dec | "0.5" | the percentage amount of borrow power each unit of deposit accounts for | | LoanToValue | Dec | "0.5" | The percentage amount of borrow power each unit of deposit accounts for |
Each `InterestRateModel` has the following parameters Example parameters for `InterestRateModel`:
| Key | Type | Example | Description | | Key | Type | Example | Description |
| ---------------- | ------ | ------- | ---------------------------------------------------------------------------------------------------------------- | | -------------- | ---- | ------- | --------------------------------------------------------------------------------------------------------------- |
| BaseRateAPY | Dec | "0.0" | the base rate of APY interest when borrows are zero. | | BaseRateAPY | Dec | "0.0" | The base rate of APY interest when borrows are zero |
| BaseMultiplier | Dec | "0.01" | the percentage rate at which the interest rate APY increases for each percentage increase in borrow utilization. | | BaseMultiplier | Dec | "0.01" | The percentage rate at which the interest rate APY increases for each percentage increase in borrow utilization |
| Kink | Dec | "0.5" | the inflection point of utilization at which the BaseMultiplier no longer applies and the JumpMultiplier does. | | Kink | Dec | "0.5" | The inflection point of utilization at which the BaseMultiplier no longer applies and the JumpMultiplier does |
| JumpMultiplier | Dec | "0.5" | same as BaseMultiplier, but only applied when utilization is above the Kink | | JumpMultiplier | Dec | "0.5" | Same as BaseMultiplier, but only applied when utilization is above the Kink |

View File

@ -4,12 +4,11 @@ order: 6
# Begin Block # Begin Block
At the start of each block, interest is accumulated, and automated liquidations are attempted At the start of each block interest is accumulated
```go ```go
// BeginBlocker updates interest rates and attempts liquidations // BeginBlocker updates interest rates
func BeginBlocker(ctx sdk.Context, k Keeper) { func BeginBlocker(ctx sdk.Context, k Keeper) {
k.ApplyInterestRateUpdates(ctx) k.ApplyInterestRateUpdates(ctx)
k.AttemptIndexLiquidations(ctx)
} }
``` ```

View File

@ -3,16 +3,11 @@ package types
// Event types for hard module // Event types for hard module
const ( const (
EventTypeHardDeposit = "hard_deposit" EventTypeHardDeposit = "hard_deposit"
EventTypeHardDelegatorDistribution = "hard_delegator_distribution"
EventTypeHardLPDistribution = "hard_lp_distribution"
EventTypeDeleteHardDeposit = "delete_hard_deposit"
EventTypeHardWithdrawal = "hard_withdrawal" EventTypeHardWithdrawal = "hard_withdrawal"
EventTypeHardBorrow = "hard_borrow" EventTypeHardBorrow = "hard_borrow"
EventTypeHardLiquidation = "hard_liquidation" EventTypeHardLiquidation = "hard_liquidation"
EventTypeHardRepay = "hard_repay" EventTypeHardRepay = "hard_repay"
AttributeValueCategory = ModuleName AttributeValueCategory = ModuleName
AttributeKeyBlockHeight = "block_height"
AttributeKeyRewardsDistribution = "rewards_distributed"
AttributeKeyDeposit = "deposit" AttributeKeyDeposit = "deposit"
AttributeKeyDepositDenom = "deposit_denom" AttributeKeyDepositDenom = "deposit_denom"
AttributeKeyDepositCoins = "deposit_coins" AttributeKeyDepositCoins = "deposit_coins"