Skip to content

Commit

Permalink
refactor(pricefeed): Rename keeper methods (#697)
Browse files Browse the repository at this point in the history
* Rename SetPrice to PostRawPrice

* Rename SetCurrentPrices to GatherRawPrices

* Remove redundant acronym syndrome on TWAP

* Update CHANGELOG.md

* Fix pricefeed names in clearing house integration tests

* Add pricefeed keeper method comments

* Fix pricefeed keeper method names

Co-authored-by: Mat-Cosmos <[email protected]>
  • Loading branch information
NibiruHeisenberg and matthiasmatt authored Jul 11, 2022
1 parent 13e1857 commit 18981b7
Show file tree
Hide file tree
Showing 27 changed files with 211 additions and 169 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* [#687](https://github.com/NibiruChain/nibiru/pull/687) Emit `PositionChangedEvent` upon changing margin.
* [#685](https://github.com/NibiruChain/nibiru/pull/685) Represent `PositionChangedEvent` bad debt as Coin.
* [#697](https://github.com/NibiruChain/nibiru/pull/697) Rename pricefeed keeper methods.
* [#689](https://github.com/NibiruChain/nibiru/pull/689) Change liquidation params to 2.5% liquidation fee ratio and 25% partial liquidation ratio.

### Testing

* [#695](https://github.com/NibiruChain/nibiru/pull/695) Add `OpenPosition` integration tests.
* [#692](https://github.com/NibiruChain/nibiru/pull/692) Add test coverage for Perp MsgServer methods.
* [#689](https://github.com/NibiruChain/nibiru/pull/689) Change liquidation params to 2.5% liquidation fee ratio and 25% partial liquidation ratio.
4 changes: 2 additions & 2 deletions app/ibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ func SetupNibiruTestingApp() (
})
nibiruApp.PricefeedKeeper.WhitelistOracles(ctx, []sdk.AccAddress{oracle})

_, err = nibiruApp.PricefeedKeeper.SetPrice(
_, err = nibiruApp.PricefeedKeeper.PostRawPrice(
ctx, oracle, pair.String(), sdk.OneDec(),
ctx.BlockTime().Add(time.Hour),
)
if err != nil {
return nil, defaultGenesis
}

err = nibiruApp.PricefeedKeeper.SetCurrentPrices(ctx, pair.Token0, pair.Token1)
err = nibiruApp.PricefeedKeeper.GatherRawPrices(ctx, pair.Token0, pair.Token1)
if err != nil {
return nil, defaultGenesis
}
Expand Down
8 changes: 4 additions & 4 deletions x/perp/keeper/clearing_house_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,9 @@ func TestOpenPositionSuccess(t *testing.T) {

t.Log("set pricefeed oracle")
nibiruApp.PricefeedKeeper.WhitelistOracles(ctx, []sdk.AccAddress{oracle})
_, err := nibiruApp.PricefeedKeeper.SetPrice(ctx, oracle, common.PairBTCStable.String(), sdk.OneDec(), time.Now().Add(time.Hour))
_, err := nibiruApp.PricefeedKeeper.PostRawPrice(ctx, oracle, common.PairBTCStable.String(), sdk.OneDec(), time.Now().Add(time.Hour))
require.NoError(t, err)
require.NoError(t, nibiruApp.PricefeedKeeper.SetCurrentPrices(ctx, common.DenomAxlBTC, common.DenomStable))
require.NoError(t, nibiruApp.PricefeedKeeper.GatherRawPrices(ctx, common.DenomAxlBTC, common.DenomStable))

t.Log("initialize vpool")
nibiruApp.VpoolKeeper.CreatePool(
Expand Down Expand Up @@ -302,9 +302,9 @@ func TestOpenPositionError(t *testing.T) {

t.Log("set pricefeed oracle")
nibiruApp.PricefeedKeeper.WhitelistOracles(ctx, []sdk.AccAddress{oracle})
_, err := nibiruApp.PricefeedKeeper.SetPrice(ctx, oracle, common.PairBTCStable.String(), sdk.OneDec(), time.Now().Add(time.Hour))
_, err := nibiruApp.PricefeedKeeper.PostRawPrice(ctx, oracle, common.PairBTCStable.String(), sdk.OneDec(), time.Now().Add(time.Hour))
require.NoError(t, err)
require.NoError(t, nibiruApp.PricefeedKeeper.SetCurrentPrices(ctx, common.DenomAxlBTC, common.DenomStable))
require.NoError(t, nibiruApp.PricefeedKeeper.GatherRawPrices(ctx, common.DenomAxlBTC, common.DenomStable))

t.Log("initialize vpool")
nibiruApp.VpoolKeeper.CreatePool(
Expand Down
10 changes: 5 additions & 5 deletions x/perp/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,27 @@ func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, _ int64)
ctx.Logger().Error("no pool for pair found", "pairMetadata.Pair", pairMetadata.Pair)
continue
}
indexTWAPPrice, err := k.PricefeedKeeper.GetCurrentTWAPPrice(ctx, pairMetadata.Pair.Token0, pairMetadata.Pair.Token1)
indexTWAP, err := k.PricefeedKeeper.GetCurrentTWAP(ctx, pairMetadata.Pair.Token0, pairMetadata.Pair.Token1)
if err != nil {
ctx.Logger().Error("failed to fetch twap index price", "pairMetadata.Pair", pairMetadata.Pair, "error", err)
continue
}
if indexTWAPPrice.Price.IsZero() {
if indexTWAP.Price.IsZero() {
ctx.Logger().Error("index price is zero", "pairMetadata.Pair", pairMetadata.Pair)
continue
}
markTWAPPrice, err := k.VpoolKeeper.GetCurrentTWAPPrice(ctx, pairMetadata.Pair)
markTWAP, err := k.VpoolKeeper.GetCurrentTWAP(ctx, pairMetadata.Pair)
if err != nil {
ctx.Logger().Error("failed to fetch twap mark price", "pairMetadata.Pair", pairMetadata.Pair, "error", err)
continue
}
if markTWAPPrice.Price.IsZero() {
if markTWAP.Price.IsZero() {
ctx.Logger().Error("mark price is zero", "pairMetadata.Pair", pairMetadata.Pair)
continue
}
epochInfo := k.EpochKeeper.GetEpochInfo(ctx, epochIdentifier)
intervalsPerDay := (24 * time.Hour) / epochInfo.Duration
fundingRate := markTWAPPrice.Price.Sub(indexTWAPPrice.Price).QuoInt64(int64(intervalsPerDay))
fundingRate := markTWAP.Price.Sub(indexTWAP.Price).QuoInt64(int64(intervalsPerDay))

if len(pairMetadata.CumulativePremiumFractions) > 0 {
fundingRate = pairMetadata.CumulativePremiumFractions[len(pairMetadata.CumulativePremiumFractions)-1].Add(fundingRate)
Expand Down
4 changes: 2 additions & 2 deletions x/perp/keeper/hooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,13 @@ func setMockPrices(ctx sdk.Context, mocks mockedDependencies, indexPrice, markPr
)
}
mocks.mockPricefeedKeeper.EXPECT().
GetCurrentTWAPPrice(ctx, common.PairBTCStable.Token0, common.PairBTCStable.Token1).
GetCurrentTWAP(ctx, common.PairBTCStable.Token0, common.PairBTCStable.Token1).
Return(pftypes.CurrentTWAP{
PairID: common.PairBTCStable.String(),
Price: sdk.NewDec(indexPrice),
}, nil).MaxTimes(1)
mocks.mockVpoolKeeper.EXPECT().
GetCurrentTWAPPrice(ctx, common.PairBTCStable).
GetCurrentTWAP(ctx, common.PairBTCStable).
Return(vpooltypes.CurrentTWAP{
PairID: common.PairBTCStable.String(),
Price: sdk.NewDec(markPrice),
Expand Down
6 changes: 3 additions & 3 deletions x/perp/keeper/margin.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ func (k Keeper) getPreferencePositionNotionalAndUnrealizedPnL(
return sdk.Dec{}, sdk.Dec{}, err
}

twapPositionNotional, twapPricePnL, err := k.getPositionNotionalAndUnrealizedPnL(
twapPositionNotional, twapPnl, err := k.getPositionNotionalAndUnrealizedPnL(
ctx,
position,
types.PnLCalcOption_TWAP,
Expand All @@ -457,10 +457,10 @@ func (k Keeper) getPreferencePositionNotionalAndUnrealizedPnL(
switch pnLPreferenceOption {
case types.PnLPreferenceOption_MAX:
positionNotional = sdk.MaxDec(spotPositionNotional, twapPositionNotional)
unrealizedPnl = sdk.MaxDec(spotPricePnl, twapPricePnL)
unrealizedPnl = sdk.MaxDec(spotPricePnl, twapPnl)
case types.PnLPreferenceOption_MIN:
positionNotional = sdk.MinDec(spotPositionNotional, twapPositionNotional)
unrealizedPnl = sdk.MinDec(spotPricePnl, twapPricePnL)
unrealizedPnl = sdk.MinDec(spotPricePnl, twapPnl)
default:
panic("invalid pnl preference option " + pnLPreferenceOption.String())
}
Expand Down
4 changes: 2 additions & 2 deletions x/perp/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,9 @@ func TestMsgServerLiquidate(t *testing.T) {
t.Log("set pricefeed oracle price")
oracle := sample.AccAddress()
app.PricefeedKeeper.WhitelistOracles(ctx, []sdk.AccAddress{oracle})
_, err = app.PricefeedKeeper.SetPrice(ctx, oracle, pair.String(), sdk.OneDec(), time.Now().Add(time.Hour))
_, err = app.PricefeedKeeper.PostRawPrice(ctx, oracle, pair.String(), sdk.OneDec(), time.Now().Add(time.Hour))
require.NoError(t, err)
require.NoError(t, app.PricefeedKeeper.SetCurrentPrices(ctx, pair.GetBaseTokenDenom(), pair.GetQuoteTokenDenom()))
require.NoError(t, app.PricefeedKeeper.GatherRawPrices(ctx, pair.GetBaseTokenDenom(), pair.GetQuoteTokenDenom()))

t.Log("create position")
require.NoError(t, app.PerpKeeper.PositionsState(ctx).Create(&types.Position{
Expand Down
30 changes: 26 additions & 4 deletions x/perp/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ type BankKeeper interface {
}

type PricefeedKeeper interface {
/* GetCurrentPrice fetches the current median price of all oracles for a specific market.
args:
- ctx: cosmos-sdk context
- token0: the base asset
- token1: the quote asset
ret:
- currPrice: the current price
- err: error if any
*/
GetCurrentPrice(ctx sdk.Context, token0 string, token1 string,
) (pftypes.CurrentPrice, error)
GetCurrentPrices(ctx sdk.Context) pftypes.CurrentPrices
Expand All @@ -59,8 +70,19 @@ type PricefeedKeeper interface {
IsWhitelistedOracle(ctx sdk.Context, pairID string, address sdk.AccAddress,
) bool
GetOraclesForPair(ctx sdk.Context, pairID string) (oracles []sdk.AccAddress)
SetCurrentPrices(ctx sdk.Context, token0 string, token1 string) error
GetCurrentTWAPPrice(ctx sdk.Context, token0 string, token1 string) (pftypes.CurrentTWAP, error)

/* GatherRawPrices updates the current price of an asset to the median of all valid posted oracle prices.
args:
- ctx: cosmos-sdk context
- token0: the base asset
- token1: the quote asset
ret:
- err: error if any
*/
GatherRawPrices(ctx sdk.Context, token0 string, token1 string) error
GetCurrentTWAP(ctx sdk.Context, token0 string, token1 string) (pftypes.CurrentTWAP, error)
}

type VpoolKeeper interface {
Expand Down Expand Up @@ -238,8 +260,8 @@ type VpoolKeeper interface {
ExistsPool(ctx sdk.Context, pair common.AssetPair) bool
GetSettlementPrice(ctx sdk.Context, pair common.AssetPair) (sdk.Dec, error)

// GetCurrentTWAPPrice fetches the TWAP for the specified token pair / pool
GetCurrentTWAPPrice(ctx sdk.Context, pair common.AssetPair) (vpooltypes.CurrentTWAP, error)
// GetCurrentTWAP fetches the TWAP for the specified token pair / pool
GetCurrentTWAP(ctx sdk.Context, pair common.AssetPair) (vpooltypes.CurrentTWAP, error)
}

type EpochKeeper interface {
Expand Down
2 changes: 1 addition & 1 deletion x/pricefeed/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
continue
}

err := k.SetCurrentPrices(ctx, pair.Token0, pair.Token1)
err := k.GatherRawPrices(ctx, pair.Token0, pair.Token1)
if err != nil && !errors.Is(err, types.ErrNoValidPrice) {
panic(err)
}
Expand Down
8 changes: 4 additions & 4 deletions x/pricefeed/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestTWAPriceUpdates(t *testing.T) {
pricefeed.BeginBlocker(ctx, nibiruApp.PricefeedKeeper)
}
setPrice := func(price string) {
_, err := nibiruApp.PricefeedKeeper.SetPrice(
_, err := nibiruApp.PricefeedKeeper.PostRawPrice(
ctx, oracle, pair.String(),
sdk.MustNewDecFromStr(price), ctx.BlockTime().Add(time.Hour*5000*4))
require.NoError(t, err)
Expand Down Expand Up @@ -68,7 +68,7 @@ func TestTWAPriceUpdates(t *testing.T) {
(0.9 * 1463385600 + (0.9 + 0.8) / 2 * 1481385600) / (1463385600 + 1481385600) = 0.8749844622444971
*/

price, err := nibiruApp.PricefeedKeeper.GetCurrentTWAPPrice(
price, err := nibiruApp.PricefeedKeeper.GetCurrentTWAP(
ctx, pair.Token0, pair.Token1)
require.NoError(t, err)
priceFloat, err := price.Price.Float64()
Expand All @@ -88,7 +88,7 @@ func TestTWAPriceUpdates(t *testing.T) {
(0.9 * 1463385600 + (0.9 + 0.8) / 2 * 1481385600 + 0.82 * 1499385600) / (1463385600 + 1481385600 + 1499385600) = 0.8563426456960295
*/
price, err = nibiruApp.PricefeedKeeper.GetCurrentTWAPPrice(
price, err = nibiruApp.PricefeedKeeper.GetCurrentTWAP(
ctx, pair.Token0, pair.Token1)
require.NoError(t, err)
priceFloat, err = price.Price.Float64()
Expand All @@ -108,7 +108,7 @@ func TestTWAPriceUpdates(t *testing.T) {
*/
setPrice("0.83")
runBlock(time.Hour * 5000)
price, err = nibiruApp.PricefeedKeeper.GetCurrentTWAPPrice(
price, err = nibiruApp.PricefeedKeeper.GetCurrentTWAP(
ctx, pair.Token0, pair.Token1)

require.NoError(t, err)
Expand Down
8 changes: 3 additions & 5 deletions x/pricefeed/client/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,19 @@ import (
"testing"
"time"

simappparams "github.com/cosmos/cosmos-sdk/simapp/params"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
sdktestutil "github.com/cosmos/cosmos-sdk/testutil"
sdktestutilcli "github.com/cosmos/cosmos-sdk/testutil/cli"
sdk "github.com/cosmos/cosmos-sdk/types"
govcli "github.com/cosmos/cosmos-sdk/x/gov/client/cli"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/suite"
tmcli "github.com/tendermint/tendermint/libs/cli"

govcli "github.com/cosmos/cosmos-sdk/x/gov/client/cli"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"

"github.com/NibiruChain/nibiru/app"
"github.com/NibiruChain/nibiru/x/common"
"github.com/NibiruChain/nibiru/x/pricefeed/client/cli"
Expand Down
4 changes: 2 additions & 2 deletions x/pricefeed/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState)
for _, pp := range genState.PostedPrices {
if pp.Expiry.After(ctx.BlockTime()) {
oracle := sdk.MustAccAddressFromBech32(pp.Oracle)
_, err := k.SetPrice(ctx, oracle, pp.PairID, pp.Price, pp.Expiry)
_, err := k.PostRawPrice(ctx, oracle, pp.PairID, pp.Price, pp.Expiry)
if err != nil {
panic(err)
}
Expand All @@ -42,7 +42,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState)
if len(postedPrices) == 0 {
continue
}
err := k.SetCurrentPrices(ctx, pair.Token0, pair.Token1)
err := k.GatherRawPrices(ctx, pair.Token0, pair.Token1)
if err != nil {
panic(err)
}
Expand Down
47 changes: 34 additions & 13 deletions x/pricefeed/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
}

// SetPrice updates the posted price for a specific oracle
func (k Keeper) SetPrice(
// PostRawPrice updates the posted price for a specific oracle
func (k Keeper) PostRawPrice(
ctx sdk.Context,
oracle sdk.AccAddress,
pairStr string,
Expand Down Expand Up @@ -104,8 +104,18 @@ func (k Keeper) SetPrice(
return newPostedPrice, nil
}

// SetCurrentPrices updates the price of an asset to the median of all valid oracle inputs
func (k Keeper) SetCurrentPrices(ctx sdk.Context, token0 string, token1 string) error {
/*
GatherRawPrices updates the current price of an asset to the median of all valid posted oracle prices.
args:
- ctx: cosmos-sdk context
- token0: the base asset
- token1: the quote asset
ret:
- err: error if any
*/
func (k Keeper) GatherRawPrices(ctx sdk.Context, token0 string, token1 string) error {
assetPair := common.AssetPair{Token0: token0, Token1: token1}
pairID := assetPair.String()

Expand Down Expand Up @@ -158,7 +168,7 @@ func (k Keeper) SetCurrentPrices(ctx sdk.Context, token0 string, token1 string)
k.setCurrentPrice(ctx, pairID, currentPrice)

// Update the TWA prices
err = k.updateTWAPPrice(ctx, pairID)
err = k.updateTWAP(ctx, pairID)
if err != nil {
return err
}
Expand All @@ -171,7 +181,7 @@ func (k Keeper) setCurrentPrice(ctx sdk.Context, pairID string, currentPrice typ
store.Set(types.CurrentPriceKey(pairID), k.cdc.MustMarshal(&currentPrice))
}

/* updateTWAPPrice updates the twap price for a token0, token1 pair
/* updateTWAP updates the twap price for a token0, token1 pair
We use the blocktime to update the twap price.
Calculation is done as follow:
Expand All @@ -182,7 +192,7 @@ With
*/

func (k Keeper) updateTWAPPrice(ctx sdk.Context, pairID string) error {
func (k Keeper) updateTWAP(ctx sdk.Context, pairID string) error {
tokens := common.DenomsFromPoolName(pairID)
token0, token1 := tokens[0], tokens[1]

Expand All @@ -191,7 +201,7 @@ func (k Keeper) updateTWAPPrice(ctx sdk.Context, pairID string) error {
return err
}

currentTWAP, err := k.GetCurrentTWAPPrice(ctx, token0, token1)
currentTWAP, err := k.GetCurrentTWAP(ctx, token0, token1)
// Err there means no twap price have been set yet for this pair
if err != nil {
currentTWAP = types.CurrentTWAP{
Expand All @@ -214,7 +224,7 @@ func (k Keeper) updateTWAPPrice(ctx sdk.Context, pairID string) error {
Price: newNumerator.Quo(newDenominator),
}
store := ctx.KVStore(k.storeKey)
store.Set(types.CurrentTWAPPriceKey("twap-"+pairID), k.cdc.MustMarshal(&newTWAP))
store.Set(types.CurrentTWAPKey("twap-"+pairID), k.cdc.MustMarshal(&newTWAP))

return nil
}
Expand Down Expand Up @@ -246,7 +256,18 @@ func (k Keeper) calculateMeanPrice(priceA, priceB types.CurrentPrice) sdk.Dec {
return mean
}

// GetCurrentPrice fetches the current median price of all oracles for a specific market
/*
GetCurrentPrice fetches the current median price of all oracles for a specific market.
args:
- ctx: cosmos-sdk context
- token0: the base asset
- token1: the quote asset
ret:
- currPrice: the current price
- err: error if any
*/
func (k Keeper) GetCurrentPrice(ctx sdk.Context, token0 string, token1 string,
) (currPrice types.CurrentPrice, err error) {
pair := common.AssetPair{Token0: token0, Token1: token1}
Expand Down Expand Up @@ -280,8 +301,8 @@ func (k Keeper) GetCurrentPrice(ctx sdk.Context, token0 string, token1 string,
return price, nil
}

// GetCurrentTWAPPrice fetches the current median price of all oracles for a specific market
func (k Keeper) GetCurrentTWAPPrice(ctx sdk.Context, token0 string, token1 string) (currPrice types.CurrentTWAP, err error) {
// GetCurrentTWAP fetches the current median price of all oracles for a specific market
func (k Keeper) GetCurrentTWAP(ctx sdk.Context, token0 string, token1 string) (currPrice types.CurrentTWAP, err error) {
pair := common.AssetPair{Token0: token0, Token1: token1}
givenIsActive := k.IsActivePair(ctx, pair.String())
inverseIsActive := k.IsActivePair(ctx, pair.Inverse().String())
Expand All @@ -296,7 +317,7 @@ func (k Keeper) GetCurrentTWAPPrice(ctx sdk.Context, token0 string, token1 strin
}

store := ctx.KVStore(k.storeKey)
bz := store.Get(types.CurrentTWAPPriceKey("twap-" + pair.String()))
bz := store.Get(types.CurrentTWAPKey("twap-" + pair.String()))

if bz == nil {
return types.CurrentTWAP{}, types.ErrNoValidTWAP
Expand Down
Loading

0 comments on commit 18981b7

Please sign in to comment.