Skip to content

Commit

Permalink
[TRA-611] Get MarketPrice exponent from marketmap (#2324)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyaoy authored Oct 1, 2024
1 parent b57eb4c commit 1085e59
Show file tree
Hide file tree
Showing 23 changed files with 284 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ export interface MarketParam {
* For example if `Exponent == -5` then a `Value` of `1,000,000,000`
* represents ``$10,000`. Therefore `10 ^ Exponent` represents the smallest
* price step (in dollars) that can be recorded.
*
* Deprecated since v7.1.x. This value is now determined from the marketmap.
*/

/** @deprecated */

exponent: number;
/**
* The minimum number of exchanges that should be reporting a live price for
Expand Down Expand Up @@ -58,8 +62,12 @@ export interface MarketParamSDKType {
* For example if `Exponent == -5` then a `Value` of `1,000,000,000`
* represents ``$10,000`. Therefore `10 ^ Exponent` represents the smallest
* price step (in dollars) that can be recorded.
*
* Deprecated since v7.1.x. This value is now determined from the marketmap.
*/

/** @deprecated */

exponent: number;
/**
* The minimum number of exchanges that should be reporting a live price for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export interface MarketPrice {
/**
* Static value. The exponent of the price. See the comment on the duplicate
* MarketParam field for more information.
*
* As of v7.1.x, this value is determined from the marketmap instead of
* needing to match the MarketParam field.
*/

exponent: number;
Expand All @@ -26,6 +29,9 @@ export interface MarketPriceSDKType {
/**
* Static value. The exponent of the price. See the comment on the duplicate
* MarketParam field for more information.
*
* As of v7.1.x, this value is determined from the marketmap instead of
* needing to match the MarketParam field.
*/

exponent: number;
Expand Down
4 changes: 3 additions & 1 deletion proto/dydxprotocol/prices/market_param.proto
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ message MarketParam {
// For example if `Exponent == -5` then a `Value` of `1,000,000,000`
// represents ``$10,000`. Therefore `10 ^ Exponent` represents the smallest
// price step (in dollars) that can be recorded.
sint32 exponent = 3;
//
// Deprecated since v7.1.x. This value is now determined from the marketmap.
sint32 exponent = 3 [ deprecated = true ];

// The minimum number of exchanges that should be reporting a live price for
// a price update to be considered valid.
Expand Down
3 changes: 3 additions & 0 deletions proto/dydxprotocol/prices/market_price.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ message MarketPrice {

// Static value. The exponent of the price. See the comment on the duplicate
// MarketParam field for more information.
//
// As of v7.1.x, this value is determined from the marketmap instead of
// needing to match the MarketParam field.
sint32 exponent = 2;

// The variable value that is updated by oracle price updates. `0` if it has
Expand Down
13 changes: 7 additions & 6 deletions protocol/app/ante/market_update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import (
"math/rand"
"testing"

sdkmath "cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"

sdkmath "cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/tx"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
Expand Down Expand Up @@ -184,7 +185,7 @@ var (
Base: "TESTING",
Quote: "USD",
},
Decimals: 1,
Decimals: 8,
MinProviderCount: 1,
Enabled: false,
Metadata_JSON: "",
Expand All @@ -198,7 +199,7 @@ var (
Base: "TESTING",
Quote: "USD",
},
Decimals: 1,
Decimals: 8,
MinProviderCount: 1,
Enabled: false,
Metadata_JSON: "",
Expand Down Expand Up @@ -236,7 +237,7 @@ var (
Base: "TESTING",
Quote: "USD",
},
Decimals: 1,
Decimals: 8,
MinProviderCount: 1,
Enabled: true,
Metadata_JSON: "",
Expand All @@ -255,7 +256,7 @@ var (
Base: "TESTING",
Quote: "USD",
},
Decimals: 1,
Decimals: 8,
MinProviderCount: 1,
Enabled: true,
Metadata_JSON: "",
Expand Down Expand Up @@ -841,7 +842,7 @@ func TestValidateMarketUpdateDecorator_AnteHandle(t *testing.T) {
ctx,
mmtypes.Market{
Ticker: mmtypes.Ticker{
Decimals: uint64(pair.market.Exponent),
Decimals: uint64(pair.market.Exponent * -1),
Enabled: false, // will be enabled later
CurrencyPair: cp,
},
Expand Down
28 changes: 28 additions & 0 deletions protocol/mocks/PricesKeeper.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 0 additions & 14 deletions protocol/testing/e2e/gov/prices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,6 @@ func TestUpdateMarketParam(t *testing.T) {
},
expectedProposalStatus: govtypesv1.ProposalStatus_PROPOSAL_STATUS_FAILED,
},
"Failure: exponent is updated": {
msg: &pricestypes.MsgUpdateMarketParam{
Authority: lib.GovModuleAddress.String(),
MarketParam: pricestypes.MarketParam{
Id: MODIFIED_MARKET_PARAM.Id,
Pair: MODIFIED_MARKET_PARAM.Pair,
Exponent: MODIFIED_MARKET_PARAM.Exponent + 1, // update to exponent is not permitted.
MinExchanges: MODIFIED_MARKET_PARAM.MinExchanges,
MinPriceChangePpm: MODIFIED_MARKET_PARAM.MinPriceChangePpm,
ExchangeConfigJson: MODIFIED_MARKET_PARAM.ExchangeConfigJson,
},
},
expectedProposalStatus: govtypesv1.ProposalStatus_PROPOSAL_STATUS_FAILED,
},
"Failure: empty pair": {
msg: &pricestypes.MsgUpdateMarketParam{
Authority: lib.GovModuleAddress.String(),
Expand Down
10 changes: 8 additions & 2 deletions protocol/testutil/app/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,17 @@ func MustMakeOrderFromHumanInput(
if !exists {
panic(fmt.Sprintf("marketParam does not exist: %v", perp.Params.MarketId))
}
marketPrice := pricestest.MustHumanPriceToMarketPrice(humanPrice, marketParams.Exponent)

exponent, err := app.PricesKeeper.GetExponent(ctx, marketParams.Pair)
if err != nil {
panic(err)
}

marketPrice := pricestest.MustHumanPriceToMarketPrice(humanPrice, exponent)
subticks := clobtypes.PriceToSubticks(
pricestypes.MarketPrice{
Price: marketPrice,
Exponent: marketParams.Exponent,
Exponent: exponent,
},
clobPair,
perp.Params.AtomicResolution,
Expand Down
12 changes: 6 additions & 6 deletions protocol/testutil/constants/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -4007,7 +4007,7 @@ const GenesisState = `{
},
{
"exchange_config_json": "{\"exchanges\":[{\"exchangeName\":\"Binance\",\"ticker\":\"\\\"LINKUSDT\\\"\"},{\"exchangeName\":\"BinanceUS\",\"ticker\":\"\\\"LINKUSD\\\"\"},{\"exchangeName\":\"CoinbasePro\",\"ticker\":\"LINK-USD\"},{\"exchangeName\":\"CryptoCom\",\"ticker\":\"LINK_USD\"},{\"exchangeName\":\"Huobi\",\"ticker\":\"linkusdt\"},{\"exchangeName\":\"Kraken\",\"ticker\":\"LINKUSD\"},{\"exchangeName\":\"Kucoin\",\"ticker\":\"LINK-USDT\"},{\"exchangeName\":\"Okx\",\"ticker\":\"LINK-USDT\"}]}",
"exponent": -8,
"exponent": -9,
"id": 2,
"min_exchanges": 1,
"min_price_change_ppm": 2000,
Expand Down Expand Up @@ -4175,7 +4175,7 @@ const GenesisState = `{
},
{
"exchange_config_json": "{\"exchanges\":[{\"exchangeName\":\"Binance\",\"ticker\":\"\\\"MKRUSDT\\\"\"},{\"exchangeName\":\"BinanceUS\",\"ticker\":\"\\\"MKRUSD\\\"\"},{\"exchangeName\":\"Bitfinex\",\"ticker\":\"tMKRUSD\"},{\"exchangeName\":\"CoinbasePro\",\"ticker\":\"MKR-USD\"},{\"exchangeName\":\"Gate\",\"ticker\":\"MKR_USDT\"},{\"exchangeName\":\"Huobi\",\"ticker\":\"mkrusdt\"},{\"exchangeName\":\"Kucoin\",\"ticker\":\"MKR-USDT\"},{\"exchangeName\":\"Okx\",\"ticker\":\"MKR-USDT\"}]}",
"exponent": -7,
"exponent": -6,
"id": 23,
"min_exchanges": 1,
"min_price_change_ppm": 2000,
Expand All @@ -4191,7 +4191,7 @@ const GenesisState = `{
},
{
"exchange_config_json": "{\"exchanges\":[{\"exchangeName\":\"Binance\",\"ticker\":\"\\\"XLMUSDT\\\"\"},{\"exchangeName\":\"BinanceUS\",\"ticker\":\"\\\"XLMUSD\\\"\"},{\"exchangeName\":\"Bitfinex\",\"ticker\":\"tXLMUSD\"},{\"exchangeName\":\"CoinbasePro\",\"ticker\":\"XLM-USD\"},{\"exchangeName\":\"Gate\",\"ticker\":\"XLM_USDT\"},{\"exchangeName\":\"Kraken\",\"ticker\":\"XXLMZUSD\"},{\"exchangeName\":\"Kucoin\",\"ticker\":\"XLM-USDT\"},{\"exchangeName\":\"Okx\",\"ticker\":\"XLM-USDT\"}]}",
"exponent": -11,
"exponent": -10,
"id": 25,
"min_exchanges": 1,
"min_price_change_ppm": 2000,
Expand Down Expand Up @@ -4266,7 +4266,7 @@ const GenesisState = `{
"price": 1500000000
},
{
"exponent": -8,
"exponent": -9,
"id": 2,
"price": 700000000
},
Expand Down Expand Up @@ -4371,7 +4371,7 @@ const GenesisState = `{
"price": 2200000000
},
{
"exponent": -7,
"exponent": -6,
"id": 23,
"price": 7100000000
},
Expand All @@ -4381,7 +4381,7 @@ const GenesisState = `{
"price": 7000000000
},
{
"exponent": -11,
"exponent": -10,
"id": 25,
"price": 10000000000
},
Expand Down
31 changes: 29 additions & 2 deletions protocol/x/prices/keeper/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,22 @@ func (k Keeper) CreateMarket(
)
}
currencyPairStr := currencyPair.String()
_, err = k.MarketMapKeeper.GetMarket(ctx, currencyPairStr)
marketMapDetails, err := k.MarketMapKeeper.GetMarket(ctx, currencyPairStr)
if err != nil {
return types.MarketParam{}, errorsmod.Wrapf(
types.ErrTickerNotFoundInMarketMap,
currencyPairStr,
)
}

// Check that the exponent of market price is the negation of the decimals value in the market map
if marketPrice.Exponent != int32(marketMapDetails.Ticker.Decimals)*-1 {
return types.MarketParam{}, errorsmod.Wrapf(
types.ErrInvalidMarketPriceExponent,
currencyPairStr,
)
}

paramBytes := k.cdc.MustMarshal(&marketParam)
priceBytes := k.cdc.MustMarshal(&marketPrice)

Expand All @@ -87,7 +95,8 @@ func (k Keeper) CreateMarket(
marketParam.Id,
marketParam.Pair,
marketParam.MinPriceChangePpm,
marketParam.Exponent,
// The exponent in market price is the source of truth, the exponent of the param is deprecated as of v7.1.x
marketPrice.Exponent,
),
),
)
Expand All @@ -111,6 +120,24 @@ func (k Keeper) CreateMarket(
return marketParam, nil
}

// Get the exponent for a market as the negation of the decimals value in the market map
func (k Keeper) GetExponent(ctx sdk.Context, ticker string) (int32, error) {
currencyPair, err := slinky.MarketPairToCurrencyPair(ticker)
if err != nil {
k.Logger(ctx).Error("Could not convert market pair to currency pair", "error", err)
return 0, err
}

marketMapDetails, err := k.MarketMapKeeper.GetMarket(ctx, currencyPair.String())
if err != nil {
return 0, errorsmod.Wrapf(
types.ErrTickerNotFoundInMarketMap,
ticker,
)
}
return int32(marketMapDetails.Ticker.Decimals) * -1, nil
}

// GetAllMarketParamPrices returns a slice of MarketParam, MarketPrice tuples for all markets.
func (k Keeper) GetAllMarketParamPrices(ctx sdk.Context) ([]types.MarketParamPrice, error) {
marketParams := k.GetAllMarketParams(ctx)
Expand Down
4 changes: 0 additions & 4 deletions protocol/x/prices/keeper/market_param.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ func (k Keeper) ModifyMarketParam(
}

// Validate update is permitted.
if updatedMarketParam.Exponent != existingParam.Exponent {
return types.MarketParam{},
errorsmod.Wrapf(types.ErrMarketExponentCannotBeUpdated, lib.UintToString(updatedMarketParam.Id))
}
for _, market := range k.GetAllMarketParams(ctx) {
if market.Pair == updatedMarketParam.Pair && market.Id != updatedMarketParam.Id {
return types.MarketParam{}, errorsmod.Wrapf(types.ErrMarketParamPairAlreadyExists, updatedMarketParam.Pair)
Expand Down
12 changes: 11 additions & 1 deletion protocol/x/prices/keeper/market_price.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,20 @@ func (k Keeper) GetMarketIdToValidIndexPrice(
ret := make(map[uint32]types.MarketPrice)
for _, marketParam := range allMarketParams {
if indexPrice, exists := marketIdToValidIndexPrice[marketParam.Id]; exists {
exponent, err := k.GetExponent(ctx, marketParam.Pair)
if err != nil {
k.Logger(ctx).Error(
"failed to get exponent for market",
"market id", marketParam.Id,
"market pair", marketParam.Pair,
"error", err,
)
continue
}
ret[marketParam.Id] = types.MarketPrice{
Id: marketParam.Id,
Price: indexPrice,
Exponent: marketParam.Exponent,
Exponent: exponent,
}
}
}
Expand Down
Loading

0 comments on commit 1085e59

Please sign in to comment.