Skip to content

Commit

Permalink
Merge branch 'main' into sai/docs_gmp
Browse files Browse the repository at this point in the history
  • Loading branch information
gsk967 authored Apr 19, 2024
2 parents 942d994 + f4d9bef commit 078e0ec
Show file tree
Hide file tree
Showing 13 changed files with 441 additions and 141 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Features

- [2472](https://github.com/umee-network/umee/pull/2472) un-wire the `crisis` module from umee app.
- [2500](https://github.com/umee-network/umee/pull/2500) (x/leverage): add Rewards Auction fees and `params.rewards_auction_factor`.

### Improvements

Expand Down
5 changes: 5 additions & 0 deletions proto/umee/leverage/v1/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,8 @@ message EventFundOracle {
// Assets sent to oracle module
repeated cosmos.base.v1beta1.Coin assets = 1 [(gogoproto.nullable) = false];
}

// EventFundAuction is emitted when sending rewards to auction module
message EventFundAuction {
repeated cosmos.base.v1beta1.Coin assets = 1 [(gogoproto.nullable) = false];
}
8 changes: 8 additions & 0 deletions proto/umee/leverage/v1/leverage.proto
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ message Params {
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"direct_liquidation_fee\""
];
// Rewards Auction Factor determines the portion of interest accrued on
// borrows that is sent to the auction module for the rewards auction.
// Valid values: 0-1.
string rewards_auction_factor = 7 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"oracle_reward_factor\""
];
}

// Token defines a token, along with its metadata and parameters, in the Umee
Expand Down
26 changes: 26 additions & 0 deletions swagger/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,16 @@ paths:
uTokens as liquidation rewards.
Valid values: 0-1.
rewards_auction_factor:
type: string
description: >-
Rewards Auction Factor determines the portion of interest
accrued on
borrows that is sent to the auction module for the rewards
auction.
Valid values: 0-1.
description: Params defines the parameters for the leverage module.
description: >-
Expand Down Expand Up @@ -6575,6 +6585,12 @@ definitions:
uTokens as liquidation rewards.
Valid values: 0-1.
rewards_auction_factor:
type: string
description: |-
Rewards Auction Factor determines the portion of interest accrued on
borrows that is sent to the auction module for the rewards auction.
Valid values: 0-1.
description: Params defines the parameters for the leverage module.
umee.leverage.v1.QueryAccountBalancesResponse:
Expand Down Expand Up @@ -7235,6 +7251,16 @@ definitions:
uTokens as liquidation rewards.
Valid values: 0-1.
rewards_auction_factor:
type: string
description: >-
Rewards Auction Factor determines the portion of interest accrued
on
borrows that is sent to the auction module for the rewards
auction.
Valid values: 0-1.
description: Params defines the parameters for the leverage module.
description: |-
Expand Down
4 changes: 2 additions & 2 deletions x/leverage/client/tests/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ func (s *IntegrationTests) TestLeverageScenario() {
OracleHistoricPrice: &oracleSymbolPrice,
UTokenExchangeRate: sdk.OneDec(),
// Borrow rate * (1 - ReserveFactor - OracleRewardFactor)
// 1.52 * (1 - 0.2 - 0.01) = 1.2008
Supply_APY: sdk.MustNewDecFromStr("1.2008"),
// 1.52 * (1 - 0.2 - 0.01 - 0.02)
Supply_APY: sdk.MustNewDecFromStr("1.1704"),
// This is an edge case technically - when effective supply, meaning
// module balance + total borrows, is zero, utilization (0/0) is
// interpreted as 100% so max borrow rate (152% APY) is used.
Expand Down
1 change: 1 addition & 0 deletions x/leverage/fixtures/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func Params() types.Params {
CompleteLiquidationThreshold: sdk.MustNewDecFromStr("0.1"),
MinimumCloseFactor: sdk.MustNewDecFromStr("0.01"),
OracleRewardFactor: sdk.MustNewDecFromStr("0.01"),
RewardsAuctionFactor: sdk.MustNewDecFromStr("0.02"),
SmallLiquidationSize: sdk.MustNewDecFromStr("100.00"),
DirectLiquidationFee: sdk.MustNewDecFromStr("0.1"),
}
Expand Down
13 changes: 7 additions & 6 deletions x/leverage/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,13 @@ func (s *IntegrationTestSuite) TestQuerier_MarketSummary() {
oracleSymbolPrice := sdk.MustNewDecFromStr("4.21")

expected := types.QueryMarketSummaryResponse{
SymbolDenom: "UMEE",
Exponent: 6,
OraclePrice: &oracleSymbolPrice,
OracleHistoricPrice: &oracleSymbolPrice,
UTokenExchangeRate: sdk.OneDec(),
Supply_APY: sdk.MustNewDecFromStr("1.2008"),
SymbolDenom: "UMEE",
Exponent: 6,
OraclePrice: &oracleSymbolPrice,
OracleHistoricPrice: &oracleSymbolPrice,
UTokenExchangeRate: sdk.OneDec(),
// see cli/tests "query market summary - zero supply"
Supply_APY: sdk.MustNewDecFromStr("1.1704"),
Borrow_APY: sdk.MustNewDecFromStr("1.52"),
Supplied: sdk.ZeroInt(),
Reserved: sdk.ZeroInt(),
Expand Down
17 changes: 10 additions & 7 deletions x/leverage/keeper/interest.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ func (k Keeper) DeriveSupplyAPY(ctx sdk.Context, denom string) sdk.Dec {

borrowRate := k.DeriveBorrowAPY(ctx, denom)
utilization := k.SupplyUtilization(ctx, denom)
reduction := k.GetParams(ctx).OracleRewardFactor.Add(token.ReserveFactor)
params := k.GetParams(ctx)
reduction := params.OracleRewardFactor.Add(params.RewardsAuctionFactor).Add(token.ReserveFactor)

// supply APY = borrow APY * utilization, reduced by reserve factor and oracle reward factor
return borrowRate.Mul(utilization).Mul(sdk.OneDec().Sub(reduction))
Expand Down Expand Up @@ -106,10 +107,11 @@ func (k Keeper) AccrueAllInterest(ctx sdk.Context) error {

// fetch required parameters
tokens := k.GetAllRegisteredTokens(ctx)
oracleRewardFactor := k.GetParams(ctx).OracleRewardFactor
params := k.GetParams(ctx)

// create sdk.Coins objects to track oracle rewards, new reserves, and total interest accrued
oracleRewards := sdk.NewCoins()
auctionRewards := sdk.NewCoins()
newReserves := sdk.NewCoins()
totalInterest := sdk.NewCoins()

Expand Down Expand Up @@ -148,10 +150,13 @@ func (k Keeper) AccrueAllInterest(ctx sdk.Context) error {
))
}

// calculate oracle rewards accrued for this denom
oracleRewards = oracleRewards.Add(sdk.NewCoin(
token.BaseDenom,
interestAccrued.Mul(oracleRewardFactor).TruncateInt(),
interestAccrued.Mul(params.OracleRewardFactor).TruncateInt(),
))
auctionRewards = auctionRewards.Add(sdk.NewCoin(
token.BaseDenom,
interestAccrued.Mul(params.RewardsAuctionFactor).TruncateInt(),
))
}

Expand All @@ -162,12 +167,10 @@ func (k Keeper) AccrueAllInterest(ctx sdk.Context) error {
}
}

// fund oracle reward pool
if err := k.FundOracle(ctx, oracleRewards); err != nil {
if err := k.fundModules(ctx, oracleRewards, auctionRewards); err != nil {
return err
}

// set LastInterestTime
err := k.setLastInterestTime(ctx, currentTime)
if err != nil {
return err
Expand Down
6 changes: 3 additions & 3 deletions x/leverage/keeper/interest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ func (s *IntegrationTestSuite) TestAccrueZeroInterest() {
require.Equal(sdk.MustNewDecFromStr("0.03"), borrowAPY)

// supply APY when borrow APY is 3%
// and utilization is 4%, and reservefactor is 20%, and OracleRewardFactor is 1%
// 0.03 * 0.04 * (1 - 0.21) = 0.000948
// and utilization is 4%, and reserve factor=20%, OracleRewardFactor=1% RewardsAuctionFactor=2%
// 0.03 * 0.04 * (1 - 0.2 - 0.01 - 0.02)
supplyAPY := app.LeverageKeeper.DeriveSupplyAPY(ctx, appparams.BondDenom)
require.Equal(sdk.MustNewDecFromStr("0.000948"), supplyAPY)
require.Equal(sdk.MustNewDecFromStr("0.000924"), supplyAPY)
}

func (s *IntegrationTestSuite) TestDynamicInterest() {
Expand Down
56 changes: 40 additions & 16 deletions x/leverage/keeper/oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import (
"strings"

"cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/umee-network/umee/v6/util/coin"
"github.com/umee-network/umee/v6/util/sdkutil"
"github.com/umee-network/umee/v6/x/auction"
"github.com/umee-network/umee/v6/x/leverage/types"
oracletypes "github.com/umee-network/umee/v6/x/oracle/types"
)
Expand Down Expand Up @@ -250,30 +252,52 @@ func (k Keeper) PriceRatio(ctx sdk.Context, fromDenom, toDenom string, mode type
return exponent(p1, powerDifference).Quo(p2), nil
}

// FundOracle transfers requested coins to the oracle module account, as
// fundModules transfers requested coins to other module account, as
// long as the leverage module account has sufficient unreserved assets.
func (k Keeper) FundOracle(ctx sdk.Context, requested sdk.Coins) error {
rewards := sdk.Coins{}
func (k Keeper) fundModules(ctx sdk.Context, toOracle, toAuction sdk.Coins) error {
toOracleCheck := sdk.Coins{}
toAuctionCheck := sdk.Coins{}
available := map[string]sdkmath.Int{}

// reduce rewards if they exceed unreserved module balance
for _, coin := range requested {
amountToTransfer := sdk.MinInt(coin.Amount, k.AvailableLiquidity(ctx, coin.Denom))

if amountToTransfer.IsPositive() {
rewards = rewards.Add(sdk.NewCoin(coin.Denom, amountToTransfer))
for _, o := range toOracle {
avl := k.AvailableLiquidity(ctx, o.Denom)
amt := sdk.MinInt(o.Amount, avl)
if amt.IsPositive() {
toOracleCheck = toOracleCheck.Add(sdk.NewCoin(o.Denom, amt))
avl.Sub(amt)
}
available[o.Denom] = avl
}
for _, o := range toAuction {
avl, ok := available[o.Denom]
if !ok {
avl = k.AvailableLiquidity(ctx, o.Denom)
}
amt := sdk.MinInt(o.Amount, avl)
if amt.IsPositive() {
toAuctionCheck = toAuctionCheck.Add(sdk.NewCoin(o.Denom, amt))
avl.Sub(amt)
}
available[o.Denom] = avl
}

// This action is not caused by a message so we need to make an event here
// This action is caused by end blocker, not a message handler, so we need to emit an event
k.Logger(ctx).Debug(
"funded oracle",
"amount", rewards,
"funded ",
"to oracle", toOracleCheck,
"to auction", toAuctionCheck,
)
sdkutil.Emit(&ctx, &types.EventFundOracle{Assets: rewards})

// Send rewards
if !rewards.IsZero() {
return k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, oracletypes.ModuleName, rewards)
send := k.bankKeeper.SendCoinsFromModuleToModule
if !toOracleCheck.IsZero() {
sdkutil.Emit(&ctx, &types.EventFundOracle{Assets: toOracleCheck})
if err := send(ctx, types.ModuleName, oracletypes.ModuleName, toOracleCheck); err != nil {
return err
}
}
if !toAuctionCheck.IsZero() {
sdkutil.Emit(&ctx, &types.EventFundAuction{Assets: toOracleCheck})
return send(ctx, types.ModuleName, auction.ModuleName, toAuctionCheck)
}

return nil
Expand Down
Loading

0 comments on commit 078e0ec

Please sign in to comment.