Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(proto)!: Add MaxCollateralShare, MinCollateralLiquidity, MaxSupplyUtilization #1159

Merged
merged 41 commits into from
Jul 27, 2022
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
4a0f7c2
ADR and proto changes
toteki Jul 18, 2022
5720f91
++
toteki Jul 18, 2022
70939bd
++
toteki Jul 18, 2022
261947b
Update CHANGELOG.md
toteki Jul 18, 2022
b8e0292
toc++
toteki Jul 18, 2022
7fd5685
Merge branch 'adam/tokenlimits' of github.com:umee-network/umee into …
toteki Jul 18, 2022
105dba8
fix validation
toteki Jul 19, 2022
3240fac
add error types
toteki Jul 19, 2022
c98b97d
borrow utilization -> supply utilization
toteki Jul 19, 2022
c408e2a
++
toteki Jul 19, 2022
0a04806
msg name
toteki Jul 19, 2022
26378b4
move table outside quote for scenario
toteki Jul 19, 2022
7834b1d
Format table
toteki Jul 19, 2022
4d83317
implement max supply utilization
toteki Jul 19, 2022
eed653d
Merge branch 'main' into adam/tokenlimits
toteki Jul 19, 2022
bae03c8
Merge branch 'main' into adam/tokenlimits
toteki Jul 19, 2022
c1cdfb1
lint
toteki Jul 19, 2022
19a5b1d
Add example scenario for each calculated value
toteki Jul 20, 2022
fcc0e6c
Merge branch 'main' into adam/tokenlimits
toteki Jul 20, 2022
d524628
reduce PR size
toteki Jul 25, 2022
93d13f5
Merge branch 'main' into adam/params
toteki Jul 25, 2022
558ae8a
cl--
toteki Jul 25, 2022
e86ef08
++
toteki Jul 25, 2022
4eacb3f
++
toteki Jul 25, 2022
8c63d4a
--
toteki Jul 25, 2022
43bf22f
++
toteki Jul 25, 2022
2e0aa9f
make proto-gen
toteki Jul 25, 2022
84a8787
++
toteki Jul 25, 2022
229dcd2
fix test
toteki Jul 25, 2022
1517081
Update CHANGELOG.md
toteki Jul 25, 2022
d106363
fix liveness test
toteki Jul 25, 2022
6cd585b
Merge branch 'adam/params' of github.com:umee-network/umee into adam/…
toteki Jul 25, 2022
d8bc33b
go.mod updates from running ignite cli
toteki Jul 25, 2022
b8a275f
make go-mod-tidy
toteki Jul 25, 2022
275dd1e
fix starport.ci.yml
toteki Jul 25, 2022
53883ff
Merge branch 'main' into adam/params
toteki Jul 25, 2022
8225e65
Apply suggestion batch
toteki Jul 25, 2022
841a9d1
Merge branch 'main' into adam/params
toteki Jul 25, 2022
5275615
Merge branch 'main' into adam/params
toteki Jul 26, 2022
c56ddba
Merge branch 'main' into adam/params
toteki Jul 27, 2022
5b39275
Merge branch 'main' into adam/params
toteki Jul 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
- [1094](https://github.com/umee-network/umee/pull/1094) Added TotalCollateral query.
- [1099](https://github.com/umee-network/umee/pull/1099) Added TotalBorrowed query.
- [1157](https://github.com/umee-network/umee/pull/1157) Added `PrintOrErr` util function optimizing the CLI code flow.
- [1141](https://github.com/umee-network/umee/pull/1141) Add `max_supply_utilization` and `min_collateral_liquidity` to the x/leverage token registry.

toteki marked this conversation as resolved.
Show resolved Hide resolved

### Improvements

Expand Down
31 changes: 17 additions & 14 deletions app/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,20 +107,23 @@ func IntegrationTestNetworkConfig() network.Config {

// Modify the x/leverage genesis state
leverageGenState.Registry = append(leverageGenState.Registry, leveragetypes.Token{
BaseDenom: BondDenom,
SymbolDenom: DisplayDenom,
Exponent: 6,
ReserveFactor: sdk.MustNewDecFromStr("0.100000000000000000"),
CollateralWeight: sdk.MustNewDecFromStr("0.050000000000000000"),
LiquidationThreshold: sdk.MustNewDecFromStr("0.050000000000000000"),
BaseBorrowRate: sdk.MustNewDecFromStr("0.020000000000000000"),
KinkBorrowRate: sdk.MustNewDecFromStr("0.200000000000000000"),
MaxBorrowRate: sdk.MustNewDecFromStr("1.50000000000000000"),
KinkUtilization: sdk.MustNewDecFromStr("0.200000000000000000"),
LiquidationIncentive: sdk.MustNewDecFromStr("0.180000000000000000"),
EnableMsgSupply: true,
EnableMsgBorrow: true,
Blacklist: false,
BaseDenom: BondDenom,
SymbolDenom: DisplayDenom,
Exponent: 6,
ReserveFactor: sdk.MustNewDecFromStr("0.1"),
CollateralWeight: sdk.MustNewDecFromStr("0.05"),
LiquidationThreshold: sdk.MustNewDecFromStr("0.05"),
BaseBorrowRate: sdk.MustNewDecFromStr("0.02"),
KinkBorrowRate: sdk.MustNewDecFromStr("0.2"),
MaxBorrowRate: sdk.MustNewDecFromStr("1.5"),
KinkUtilization: sdk.MustNewDecFromStr("0.2"),
LiquidationIncentive: sdk.MustNewDecFromStr("0.18"),
EnableMsgSupply: true,
EnableMsgBorrow: true,
Blacklist: false,
MaxCollateralShare: sdk.MustNewDecFromStr("1"),
MaxSupplyUtilization: sdk.MustNewDecFromStr("1"),
MinCollateralLiquidity: sdk.MustNewDecFromStr("0"),
})

// Marshal the modified state and add it back into appGenState
Expand Down
96 changes: 59 additions & 37 deletions proto/umee/leverage/v1/leverage.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,30 @@ option (gogoproto.goproto_getters_all) = false;
// Params defines the parameters for the leverage module.
message Params {
option (gogoproto.goproto_stringer) = false;
// The complete_liquidation_threshold determines how far over their borrow
// Complete Liquidation Threshold determines how far over their borrow
// limit a borrower must be in order for their positions to be liquidated
// fully in a single event.
string complete_liquidation_threshold = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"complete_liquidation_threshold\""
];
// The minimum_close_factor determines the portion of a borrower's position
// Minimum Close Factor determines the portion of a borrower's position
// that can be liquidated in a single event, when the borrower is just barely
// over their borrow limit.
string minimum_close_factor = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"minimum_close_factor\""
];
// The oracle_reward_factor determines the portion of interest accrued on
// Oracle Reward Factor determines the portion of interest accrued on
// borrows that is sent to the oracle module to fund its reward pool.
string oracle_reward_factor = 4 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"oracle_reward_factor\""
];
// The small_liquidation_size determines the USD value at which a borrow is
// Small Liquidation Size determines the USD value at which a borrow is
// considered small enough to be liquidated in a single transaction, bypassing
// dynamic close factor.
string small_liquidation_size = 5 [
Expand All @@ -43,32 +43,32 @@ message Params {
];
}

// Token defines a token, along with its capital metadata, in the Umee capital
// facility that can be supplied and borrowed.
// Token defines a token, along with its metadata and parameters, in the Umee
// capital facility that can be supplied and borrowed.
message Token {
option (gogoproto.equal) = true;

// The base_denom defines the denomination of the underlying base token.
// Base Denom is the denomination of the underlying base token.
string base_denom = 1 [(gogoproto.moretags) = "yaml:\"base_denom\""];

// The reserve factor defines what portion of accrued interest of the asset
// type goes to reserves.
// Reserve Factor defines what portion of accrued interest goes to reserves
// when this token is borrowed.
string reserve_factor = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"reserve_factor\""
];

// The collateral_weight defines what amount of the total value of the asset
// can contribute to a users borrowing power. If the collateral_weight is
// Collateral Weight defines what portion of the total value of the asset
// can contribute to a users borrowing power. If the collateral weight is
// zero, using this asset as collateral against borrowing will be disabled.
string collateral_weight = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"collateral_weight\""
];

// The liquidation_threshold defines what amount of the total value of the
// Liquidation Threshold defines what amount of the total value of the
// asset can contribute to a user's liquidation threshold (above which they
// become eligible for liquidation).
string liquidation_threshold = 4 [
Expand All @@ -77,77 +77,99 @@ message Token {
(gogoproto.moretags) = "yaml:\"liquidation_threshold\""
];

// The base_borrow_rate defines the minimum interest rate for borrowing this
// Base Borrow Rate defines the minimum interest rate for borrowing this
// asset.
string base_borrow_rate = 5 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"base_borrow_rate\""
];

// The kink_borrow_rate defines the interest rate for borrowing this
// asset when utilization equals to 'kink_utilization'.
// Kink Borrow Rate defines the interest rate for borrowing this
// asset when supply utilization is equal to 'kink_utilization'.
string kink_borrow_rate = 6 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"kink_borrow_rate\""
];

// The max_borrow_rate defines the interest rate for borrowing this
// asset (seen when supply utilization is 100%).
// Max Borrow Rate defines the interest rate for borrowing this
// asset when supply utilization is at its maximum.
string max_borrow_rate = 7 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"max_borrow_rate\""
];

// The kink_utilization defines the value where the kink rate kicks off for
// borrow rates.
// Kink Utilization defines the supply utilization value where
// the kink in the borrow interest rate function occurs.
string kink_utilization = 8 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"kink_utilization\""
];

// The liquidation_incentive determines the portion of bonus collateral of
// Liquidation Incentive determines the portion of bonus collateral of
// a token type liquidators receive as a liquidation reward.
string liquidation_incentive = 9 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"liquidation_incentive\""
];

// The symbol_denom and exponent are solely used to update the oracle's accept
// list of allowed tokens.
// Symbol Denom is the human readable denomination of this token.
string symbol_denom = 10 [(gogoproto.moretags) = "yaml:\"symbol_denom\""];

// Exponent is the power of ten by which to multiply, in order to convert
// an amount of the token denoted in its symbol denom to the actual amount
// of its base denom.
uint32 exponent = 11 [(gogoproto.moretags) = "yaml:\"exponent\""];

// Allows supplying for lending or collateral using this token. Note that
// withdrawing is always enabled. Disabling supplying would be one step in
// phasing out an asset type.
// EnableMsgSupply allows supplying for lending or collateral using this
toteki marked this conversation as resolved.
Show resolved Hide resolved
// token. Note that withdrawing is always enabled. Disabling supplying would
// be one step in phasing out an asset type.
bool enable_msg_supply = 12 [(gogoproto.moretags) = "yaml:\"enable_msg_supply\""];

// Allows borrowing of this token. Note that repaying is always enabled.
// Disabling borrowing would be one step in phasing out an asset type, but
// could also be used from the start for asset types meant to be collateral
// only, like meTokens.
// EnableMsgBorrow allows borrowing of this token. Note that repaying is
toteki marked this conversation as resolved.
Show resolved Hide resolved
// always enabled. Disabling borrowing would be one step in phasing out an
// asset type, but could also be used from the start for asset types meant
// to be collateral only, like meTokens.
bool enable_msg_borrow = 13
[(gogoproto.moretags) = "yaml:\"enable_msg_borrow\""];

// This should only be used to eliminate an asset completely. A blacklisted
// Blacklist should only be used to eliminate an asset completely. A blacklisted
// asset is treated as though its oracle price is zero, and thus ignored by
// calculations such as collateral value and borrow limit. Can still be repaid
// or withdrawn, but not liquidated. A blacklisted token must have enable_msg_supply
// and enable_msg_borrow set to false. Such tokens can be safely removed from the
// oracle and price feeder as well.
bool blacklist = 14;

// Maximum collateral share specifies how much of the
// system's overall collateral be provided by a single token.
// Value is a percent; allowed values are in [0, 100] range.
// 100 means that the token has no restriction. 10 means maximum 10% of total
// collateral value can provided by this token.
uint32 max_collateral_share = 15 [
(gogoproto.moretags) = "yaml:\"max_collateral_share\""
// Max Collateral Share specifies how much of the system's overall collateral
// can be provided by a given token. 1.0 means that the token has no restriction.
// 0.1 means maximum 10% of system's total collateral value can provided by this token.
toteki marked this conversation as resolved.
Show resolved Hide resolved
string max_collateral_share = 15 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"max_collateral_share\""
];

// Max Supply Utilization specifies the maximum supply utilization a token is
// allowed to reach as a direct result of user borrowing. It can still be exceeded
// due to withdrawals, interest, and liquidations.
toteki marked this conversation as resolved.
Show resolved Hide resolved
string max_supply_utilization = 16 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"max_supply_utilization\""
];

// Min Collateral Liquidity specifies the minimum collateral liquidity a token is
// allowed to reach as a direct result of users borrowing, collateralizing, or
// withdrawing assets. Liquidity can only drop below this value due to interest
// or liquidations.
string min_collateral_liquidity = 17 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"min_collateral_liquidity\""
];
}
31 changes: 17 additions & 14 deletions x/leverage/client/tests/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,20 +260,23 @@ func (s *IntegrationTestSuite) TestLeverageScenario() {
Registry: []types.Token{
{
// must match app/test_helpers.go/IntegrationTestNetworkConfig
BaseDenom: umeeapp.BondDenom,
SymbolDenom: umeeapp.DisplayDenom,
Exponent: 6,
ReserveFactor: sdk.MustNewDecFromStr("0.1"),
CollateralWeight: sdk.MustNewDecFromStr("0.05"),
LiquidationThreshold: sdk.MustNewDecFromStr("0.05"),
BaseBorrowRate: sdk.MustNewDecFromStr("0.02"),
KinkBorrowRate: sdk.MustNewDecFromStr("0.2"),
MaxBorrowRate: sdk.MustNewDecFromStr("1.5"),
KinkUtilization: sdk.MustNewDecFromStr("0.2"),
LiquidationIncentive: sdk.MustNewDecFromStr("0.18"),
EnableMsgSupply: true,
EnableMsgBorrow: true,
Blacklist: false,
BaseDenom: umeeapp.BondDenom,
SymbolDenom: umeeapp.DisplayDenom,
Exponent: 6,
ReserveFactor: sdk.MustNewDecFromStr("0.1"),
CollateralWeight: sdk.MustNewDecFromStr("0.05"),
LiquidationThreshold: sdk.MustNewDecFromStr("0.05"),
BaseBorrowRate: sdk.MustNewDecFromStr("0.02"),
KinkBorrowRate: sdk.MustNewDecFromStr("0.2"),
MaxBorrowRate: sdk.MustNewDecFromStr("1.5"),
KinkUtilization: sdk.MustNewDecFromStr("0.2"),
LiquidationIncentive: sdk.MustNewDecFromStr("0.18"),
EnableMsgSupply: true,
EnableMsgBorrow: true,
Blacklist: false,
MaxCollateralShare: sdk.MustNewDecFromStr("1"),
MaxSupplyUtilization: sdk.MustNewDecFromStr("1"),
MinCollateralLiquidity: sdk.MustNewDecFromStr("0"),
},
},
},
Expand Down
31 changes: 17 additions & 14 deletions x/leverage/gov_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,23 @@ import (

func newTestToken(base, symbol, reserveFactor string) types.Token {
return types.Token{
BaseDenom: base,
SymbolDenom: symbol,
Exponent: 6,
ReserveFactor: sdk.MustNewDecFromStr(reserveFactor),
CollateralWeight: sdk.MustNewDecFromStr("0.25"),
LiquidationThreshold: sdk.MustNewDecFromStr("0.25"),
BaseBorrowRate: sdk.MustNewDecFromStr("0.02"),
KinkBorrowRate: sdk.MustNewDecFromStr("0.22"),
MaxBorrowRate: sdk.MustNewDecFromStr("1.52"),
KinkUtilization: sdk.MustNewDecFromStr("0.8"),
LiquidationIncentive: sdk.MustNewDecFromStr("0.1"),
EnableMsgSupply: true,
EnableMsgBorrow: true,
Blacklist: false,
BaseDenom: base,
SymbolDenom: symbol,
Exponent: 6,
ReserveFactor: sdk.MustNewDecFromStr(reserveFactor),
CollateralWeight: sdk.MustNewDecFromStr("0.25"),
LiquidationThreshold: sdk.MustNewDecFromStr("0.25"),
BaseBorrowRate: sdk.MustNewDecFromStr("0.02"),
KinkBorrowRate: sdk.MustNewDecFromStr("0.22"),
MaxBorrowRate: sdk.MustNewDecFromStr("1.52"),
KinkUtilization: sdk.MustNewDecFromStr("0.8"),
LiquidationIncentive: sdk.MustNewDecFromStr("0.1"),
EnableMsgSupply: true,
EnableMsgBorrow: true,
Blacklist: false,
MaxCollateralShare: sdk.MustNewDecFromStr("1"),
MaxSupplyUtilization: sdk.MustNewDecFromStr("0.9"),
MinCollateralLiquidity: sdk.MustNewDecFromStr("0"),
}
}

Expand Down
2 changes: 1 addition & 1 deletion x/leverage/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func (k Keeper) getAllBadDebts(ctx sdk.Context) []types.BadDebt {
prefix := types.KeyPrefixBadDebt
badDebts := []types.BadDebt{}

iterator := func(key, val []byte) error {
iterator := func(key, _ []byte) error {
addr := types.AddressFromKey(key, prefix)
denom := types.DenomFromKeyWithAddress(key, prefix)

Expand Down
2 changes: 1 addition & 1 deletion x/leverage/keeper/interest.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (k Keeper) DeriveBorrowAPY(ctx sdk.Context, denom string) sdk.Dec {
}

// DeriveSupplyAPY derives the current supply interest rate on a token denom
// using its supply utilization borrow APY. Returns zero on invalid asset.
// using its supply utilization and borrow APY. Returns zero on invalid asset.
func (k Keeper) DeriveSupplyAPY(ctx sdk.Context, denom string) sdk.Dec {
token, err := k.GetTokenSettings(ctx, denom)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions x/leverage/keeper/invariants.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func BorrowAPYInvariant(k Keeper) sdk.Invariant {

// Iterate through all denoms of registered tokens in the
// keeper, ensuring none have a negative borrow APY.
err := k.iterate(ctx, tokenPrefix, func(key, val []byte) error {
err := k.iterate(ctx, tokenPrefix, func(key, _ []byte) error {
denom := types.DenomFromKey(key, tokenPrefix)

borrowAPY := k.DeriveBorrowAPY(ctx, denom)
Expand Down Expand Up @@ -238,7 +238,7 @@ func SupplyAPYInvariant(k Keeper) sdk.Invariant {

// Iterate through all denoms of registered tokens in the
// keeper, ensuring none have a negative supply APY.
err := k.iterate(ctx, tokenPrefix, func(key, val []byte) error {
err := k.iterate(ctx, tokenPrefix, func(key, _ []byte) error {
denom := types.DenomFromKey(key, tokenPrefix)

supplyAPY := k.DeriveSupplyAPY(ctx, denom)
Expand Down Expand Up @@ -274,7 +274,7 @@ func InterestScalarsInvariant(k Keeper) sdk.Invariant {

// Iterate through all denoms of registered tokens in the
// keeper, ensuring none have an interest scalar less than one.
err := k.iterate(ctx, tokenPrefix, func(key, val []byte) error {
err := k.iterate(ctx, tokenPrefix, func(key, _ []byte) error {
denom := types.DenomFromKey(key, tokenPrefix)

scalar := k.getInterestScalar(ctx, denom)
Expand Down
Loading