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"
)
// BeginBlocker updates interest rates and attempts liquidations
// BeginBlocker updates interest rates
func BeginBlocker(ctx sdk.Context, k Keeper) {
k.ApplyInterestRateUpdates(ctx)
}

View File

@ -8,38 +8,33 @@ import (
)
const (
AttributeKeyBlockHeight = types.AttributeKeyBlockHeight
AttributeKeyBorrow = types.AttributeKeyBorrow
AttributeKeyBorrowCoins = types.AttributeKeyBorrowCoins
AttributeKeyBorrower = types.AttributeKeyBorrower
AttributeKeyDeposit = types.AttributeKeyDeposit
AttributeKeyDepositCoins = types.AttributeKeyDepositCoins
AttributeKeyDepositDenom = types.AttributeKeyDepositDenom
AttributeKeyDepositor = types.AttributeKeyDepositor
AttributeKeyRepayCoins = types.AttributeKeyRepayCoins
AttributeKeyRewardsDistribution = types.AttributeKeyRewardsDistribution
AttributeKeySender = types.AttributeKeySender
AttributeValueCategory = types.AttributeValueCategory
DefaultParamspace = types.DefaultParamspace
EventTypeDeleteHardDeposit = types.EventTypeDeleteHardDeposit
EventTypeHardLiquidation = types.EventTypeHardLiquidation
EventTypeHardBorrow = types.EventTypeHardBorrow
EventTypeHardDelegatorDistribution = types.EventTypeHardDelegatorDistribution
EventTypeHardDeposit = types.EventTypeHardDeposit
EventTypeHardLPDistribution = types.EventTypeHardLPDistribution
EventTypeHardRepay = types.EventTypeHardRepay
EventTypeHardWithdrawal = types.EventTypeHardWithdrawal
ModuleAccountName = types.ModuleAccountName
ModuleName = types.ModuleName
QuerierRoute = types.QuerierRoute
QueryGetBorrows = types.QueryGetBorrows
QueryGetDeposits = types.QueryGetDeposits
QueryGetModuleAccounts = types.QueryGetModuleAccounts
QueryGetParams = types.QueryGetParams
QueryGetTotalBorrowed = types.QueryGetTotalBorrowed
QueryGetTotalDeposited = types.QueryGetTotalDeposited
RouterKey = types.RouterKey
StoreKey = types.StoreKey
AttributeKeyBorrow = types.AttributeKeyBorrow
AttributeKeyBorrowCoins = types.AttributeKeyBorrowCoins
AttributeKeyBorrower = types.AttributeKeyBorrower
AttributeKeyDeposit = types.AttributeKeyDeposit
AttributeKeyDepositCoins = types.AttributeKeyDepositCoins
AttributeKeyDepositDenom = types.AttributeKeyDepositDenom
AttributeKeyDepositor = types.AttributeKeyDepositor
AttributeKeyRepayCoins = types.AttributeKeyRepayCoins
AttributeKeySender = types.AttributeKeySender
AttributeValueCategory = types.AttributeValueCategory
DefaultParamspace = types.DefaultParamspace
EventTypeHardLiquidation = types.EventTypeHardLiquidation
EventTypeHardBorrow = types.EventTypeHardBorrow
EventTypeHardDeposit = types.EventTypeHardDeposit
EventTypeHardRepay = types.EventTypeHardRepay
EventTypeHardWithdrawal = types.EventTypeHardWithdrawal
ModuleAccountName = types.ModuleAccountName
ModuleName = types.ModuleName
QuerierRoute = types.QuerierRoute
QueryGetBorrows = types.QueryGetBorrows
QueryGetDeposits = types.QueryGetDeposits
QueryGetModuleAccounts = types.QueryGetModuleAccounts
QueryGetParams = types.QueryGetParams
QueryGetTotalBorrowed = types.QueryGetTotalBorrowed
QueryGetTotalDeposited = types.QueryGetTotalDeposited
RouterKey = types.RouterKey
StoreKey = types.StoreKey
)
var (

View File

@ -6,9 +6,8 @@ order: 1
## 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
[See Incentive Module](../../incentive/spec/01_concepts.md)

View File

@ -6,13 +6,19 @@ order: 2
## 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
// Params governance parameters for hard module
type Params struct {
MoneyMarkets MoneyMarkets `json:"money_markets" yaml:"money_markets"` // defines the parameters for each money market
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
MoneyMarkets MoneyMarkets `json:"money_markets" yaml:"money_markets"`
MinimumBorrowUSDValue sdk.Dec `json:"minimum_borrow_usd_value" yaml:"minimum_borrow_usd_value"`
}
// 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)
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
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
}

View File

@ -39,12 +39,13 @@ This message creates a `Borrow` object is one does not exist, or updates an exis
```go
// MsgRepay repays funds to the hard module.
type MsgRepay struct {
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
Amount sdk.Coins `json:"amount" yaml:"amount"`
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
Owner sdk.AccAddress `json:"owner" yaml:"owner"`
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
// MsgLiquidate attempts to liquidate a borrower's borrow

View File

@ -19,38 +19,28 @@ The hard module emits the following events:
### MsgWithdraw
| Type | Attribute Key | Attribute Value |
| ------------------- | ------------- | --------------------- |
| message | module | hard |
| message | sender | `{sender address}` |
| hard_withdrawal | amount | `{amount}` |
| hard_withdrawal | depositor | `{depositor address}` |
| Type | Attribute Key | Attribute Value |
| --------------- | ------------- | --------------------- |
| message | module | hard |
| message | sender | `{sender address}` |
| hard_withdrawal | amount | `{amount}` |
| hard_withdrawal | depositor | `{depositor address}` |
### MsgBorrow
| Type | Attribute Key | Attribute Value |
| -------------- | ------------- | --------------------- |
| message | module | hard |
| message | sender | `{sender address}` |
| hard_borrow | borrow_coins | `{amount}` |
| hard_withdrawal| borrower | `{borrower address}` |
| Type | Attribute Key | Attribute Value |
| --------------- | ------------- | -------------------- |
| message | module | hard |
| message | sender | `{sender address}` |
| hard_borrow | borrow_coins | `{amount}` |
| hard_withdrawal | borrower | `{borrower address}` |
### MsgRepay
| Type | Attribute Key | Attribute Value |
| -------------- | ------------- | --------------------- |
| message | module | hard |
| message | sender | `{sender address}` |
| hard_repay | repay_coins | `{amount}` |
| 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}` |
| Type | Attribute Key | Attribute Value |
| ---------- | ------------- | -------------------- |
| message | module | hard |
| message | sender | `{sender address}` |
| message | owner | `{owner address}` |
| hard_repay | repay_coins | `{amount}` |
| hard_repay | sender | `{borrower address}` |

View File

@ -4,39 +4,38 @@ order: 5
# Parameters
The hard module has the following parameters:
Example parameters for the Hard module:
| Key | Type | Example | Description |
| ------------------------------ | ------------------------------------- | ------------- | ----------------------------------------------------------------------------|
| 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 |
| Key | Type | Example | Description |
| --------------------- | ------------------- | ------------- | -------------------------------------------- |
| MoneyMarkets | array (MoneyMarket) | [{see below}] | Array of params for each supported market |
| 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 |
| ------------------------- | ------------------ | ---------------------- | --------------------------------------------------------------------- |
| 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 |
| 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 |
| 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 |
| AuctionSize | Int | "1000000000" | The maximum size of an individual auction |
| KeeperRewardPercentage | Dec | "0.02" | Percentage of deposit rewarded to keeper who liquidates a position |
| Key | Type | Example | Description |
| ---------------------- | ----------------- | ------------- | --------------------------------------------------------------------- |
| 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 |
| 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 |
| 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 |
| 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 |
| --------------------- | ------------------ | ---------------------- | ------------------------------------------------------------------------ |
| 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 |
| LoanToValue | Dec | "0.5" | the percentage amount of borrow power each unit of deposit accounts for |
| Key | Type | Example | Description |
| ------------ | ---- | ------------ | ----------------------------------------------------------------------- |
| 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 |
| 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 |
| ---------------- | ------ | ------- | ---------------------------------------------------------------------------------------------------------------- |
| 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. |
| 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 |
| Key | Type | Example | Description |
| -------------- | ---- | ------- | --------------------------------------------------------------------------------------------------------------- |
| 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 |
| 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 |

View File

@ -4,12 +4,11 @@ order: 6
# 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
// BeginBlocker updates interest rates and attempts liquidations
// BeginBlocker updates interest rates
func BeginBlocker(ctx sdk.Context, k Keeper) {
k.ApplyInterestRateUpdates(ctx)
k.AttemptIndexLiquidations(ctx)
}
```

View File

@ -2,29 +2,24 @@ package types
// Event types for hard module
const (
EventTypeHardDeposit = "hard_deposit"
EventTypeHardDelegatorDistribution = "hard_delegator_distribution"
EventTypeHardLPDistribution = "hard_lp_distribution"
EventTypeDeleteHardDeposit = "delete_hard_deposit"
EventTypeHardWithdrawal = "hard_withdrawal"
EventTypeHardBorrow = "hard_borrow"
EventTypeHardLiquidation = "hard_liquidation"
EventTypeHardRepay = "hard_repay"
AttributeValueCategory = ModuleName
AttributeKeyBlockHeight = "block_height"
AttributeKeyRewardsDistribution = "rewards_distributed"
AttributeKeyDeposit = "deposit"
AttributeKeyDepositDenom = "deposit_denom"
AttributeKeyDepositCoins = "deposit_coins"
AttributeKeyDepositor = "depositor"
AttributeKeyBorrow = "borrow"
AttributeKeyBorrower = "borrower"
AttributeKeyBorrowCoins = "borrow_coins"
AttributeKeySender = "sender"
AttributeKeyRepayCoins = "repay_coins"
AttributeKeyLiquidatedOwner = "liquidated_owner"
AttributeKeyLiquidatedCoins = "liquidated_coins"
AttributeKeyKeeper = "keeper"
AttributeKeyKeeperRewardCoins = "keeper_reward_coins"
AttributeKeyOwner = "owner"
EventTypeHardDeposit = "hard_deposit"
EventTypeHardWithdrawal = "hard_withdrawal"
EventTypeHardBorrow = "hard_borrow"
EventTypeHardLiquidation = "hard_liquidation"
EventTypeHardRepay = "hard_repay"
AttributeValueCategory = ModuleName
AttributeKeyDeposit = "deposit"
AttributeKeyDepositDenom = "deposit_denom"
AttributeKeyDepositCoins = "deposit_coins"
AttributeKeyDepositor = "depositor"
AttributeKeyBorrow = "borrow"
AttributeKeyBorrower = "borrower"
AttributeKeyBorrowCoins = "borrow_coins"
AttributeKeySender = "sender"
AttributeKeyRepayCoins = "repay_coins"
AttributeKeyLiquidatedOwner = "liquidated_owner"
AttributeKeyLiquidatedCoins = "liquidated_coins"
AttributeKeyKeeper = "keeper"
AttributeKeyKeeperRewardCoins = "keeper_reward_coins"
AttributeKeyOwner = "owner"
)