github.com/InjectiveLabs/sdk-go@v1.53.0/chain/exchange/types/params.go (about)

     1  package types
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"cosmossdk.io/math"
     7  	sdk "github.com/cosmos/cosmos-sdk/types"
     8  	paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
     9  )
    10  
    11  var _ paramtypes.ParamSet = &Params{}
    12  
    13  // Exchange params default values
    14  const (
    15  	// DefaultFundingIntervalSeconds is 3600. This represents the number of seconds in one hour which is the frequency at which
    16  	// funding is applied by default on derivative markets.
    17  	DefaultFundingIntervalSeconds int64 = 3600
    18  
    19  	// DefaultFundingMultipleSeconds is 3600. This represents the number of seconds in one hour which is multiple of the
    20  	// unix time seconds timestamp that each perpetual market's funding timestamp should be. This ensures that
    21  	// funding is consistently applied on the hour for all perpetual markets.
    22  	DefaultFundingMultipleSeconds int64 = 3600
    23  
    24  	// SpotMarketInstantListingFee is 20 INJ
    25  	SpotMarketInstantListingFee int64 = 20
    26  
    27  	// DerivativeMarketInstantListingFee is 20 INJ
    28  	DerivativeMarketInstantListingFee int64 = 20
    29  
    30  	// BinaryOptionsMarketInstantListingFee is 100 INJ
    31  	BinaryOptionsMarketInstantListingFee int64 = 100
    32  
    33  	// MaxDerivativeOrderSideCount is 20
    34  	MaxDerivativeOrderSideCount uint32 = 20
    35  
    36  	MaxOracleScaleFactor uint32 = 18
    37  
    38  	MaxTickerLength int = 40
    39  
    40  	// MaxHistoricalTradeRecordAge is the maximum age of trade records to track.
    41  	MaxHistoricalTradeRecordAge = 60 * 5
    42  
    43  	// MaxSubaccountNonceLength restricts the size of a subaccount number from 0 to 999
    44  	MaxSubaccountNonceLength = 3
    45  
    46  	// MaxGranterDelegations is the maximum number of delegations that are checked for stake granter
    47  	MaxGranterDelegations = 25
    48  )
    49  
    50  var MaxBinaryOptionsOrderPrice = math.LegacyOneDec()
    51  
    52  // would be $0.000001 for USDT
    53  var MinDerivativeOrderPrice = math.LegacyOneDec()
    54  
    55  // MaxOrderPrice equals 10^32
    56  var MaxOrderPrice = math.LegacyMustNewDecFromStr("100000000000000000000000000000000")
    57  
    58  // MaxOrderMargin equals 10^32
    59  var MaxOrderMargin = math.LegacyMustNewDecFromStr("100000000000000000000000000000000")
    60  
    61  // MaxTokenInt equals 100,000,000 * 10^18
    62  var MaxTokenInt, _ = math.NewIntFromString("100000000000000000000000000")
    63  
    64  var MaxOrderQuantity = math.LegacyMustNewDecFromStr("100000000000000000000000000000000")
    65  var MaxFeeMultiplier = math.LegacyMustNewDecFromStr("100")
    66  
    67  var minMarginRatio = math.LegacyNewDecWithPrec(5, 3)
    68  
    69  // Parameter keys
    70  var (
    71  	KeySpotMarketInstantListingFee                 = []byte("SpotMarketInstantListingFee")
    72  	KeyDerivativeMarketInstantListingFee           = []byte("DerivativeMarketInstantListingFee")
    73  	KeyDefaultSpotMakerFeeRate                     = []byte("DefaultSpotMakerFeeRate")
    74  	KeyDefaultSpotTakerFeeRate                     = []byte("DefaultSpotTakerFeeRate")
    75  	KeyDefaultDerivativeMakerFeeRate               = []byte("DefaultDerivativeMakerFeeRate")
    76  	KeyDefaultDerivativeTakerFeeRate               = []byte("DefaultDerivativeTakerFeeRate")
    77  	KeyDefaultInitialMarginRatio                   = []byte("DefaultInitialMarginRatio")
    78  	KeyDefaultMaintenanceMarginRatio               = []byte("DefaultMaintenanceMarginRatio")
    79  	KeyDefaultFundingInterval                      = []byte("DefaultFundingInterval")
    80  	KeyFundingMultiple                             = []byte("FundingMultiple")
    81  	KeyRelayerFeeShareRate                         = []byte("RelayerFeeShareRate")
    82  	KeyDefaultHourlyFundingRateCap                 = []byte("DefaultHourlyFundingRateCap")
    83  	KeyDefaultHourlyInterestRate                   = []byte("DefaultHourlyInterestRate")
    84  	KeyMaxDerivativeOrderSideCount                 = []byte("MaxDerivativeOrderSideCount")
    85  	KeyInjRewardStakedRequirementThreshold         = []byte("KeyInjRewardStakedRequirementThreshold")
    86  	KeyTradingRewardsVestingDuration               = []byte("TradingRewardsVestingDuration")
    87  	KeyLiquidatorRewardShareRate                   = []byte("LiquidatorRewardShareRate")
    88  	KeyBinaryOptionsMarketInstantListingFee        = []byte("BinaryOptionsMarketInstantListingFee")
    89  	KeyAtomicMarketOrderAccessLevel                = []byte("AtomicMarketOrderAccessLevel")
    90  	KeySpotAtomicMarketOrderFeeMultiplier          = []byte("SpotAtomicMarketOrderFeeMultiplier")
    91  	KeyDerivativeAtomicMarketOrderFeeMultiplier    = []byte("DerivativeAtomicMarketOrderFeeMultiplier")
    92  	KeyBinaryOptionsAtomicMarketOrderFeeMultiplier = []byte("BinaryOptionsAtomicMarketOrderFeeMultiplier")
    93  	KeyMinimalProtocolFeeRate                      = []byte("MinimalProtocolFeeRate")
    94  	KeyIsInstantDerivativeMarketLaunchEnabled      = []byte("IsInstantDerivativeMarketLaunchEnabled")
    95  	KeyPostOnlyModeHeightThreshold                 = []byte("PostOnlyModeHeightThreshold")
    96  )
    97  
    98  // ParamKeyTable returns the parameter key table.
    99  func ParamKeyTable() paramtypes.KeyTable {
   100  	return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
   101  }
   102  
   103  // NewParams creates a new Params instance
   104  func NewParams(
   105  	spotMarketInstantListingFee sdk.Coin,
   106  	derivativeMarketInstantListingFee sdk.Coin,
   107  	defaultSpotMakerFee math.LegacyDec,
   108  	defaultSpotTakerFee math.LegacyDec,
   109  	defaultDerivativeMakerFee math.LegacyDec,
   110  	defaultDerivativeTakerFee math.LegacyDec,
   111  	defaultInitialMarginRatio math.LegacyDec,
   112  	defaultMaintenanceMarginRatio math.LegacyDec,
   113  	defaultFundingInterval int64,
   114  	fundingMultiple int64,
   115  	relayerFeeShare math.LegacyDec,
   116  	defaultHourlyFundingRateCap math.LegacyDec,
   117  	defaultHourlyInterestRate math.LegacyDec,
   118  	maxDerivativeSideOrderCount uint32,
   119  	injRewardStakedRequirementThreshold math.Int,
   120  	tradingRewardsVestingDuration int64,
   121  	liquidatorRewardShareRate math.LegacyDec,
   122  	binaryOptionsMarketInstantListingFee sdk.Coin,
   123  	atomicMarketOrderAccessLevel AtomicMarketOrderAccessLevel,
   124  	spotAtomicMarketOrderFeeMultiplier math.LegacyDec,
   125  	derivativeAtomicMarketOrderFeeMultiplier math.LegacyDec,
   126  	binaryOptionsAtomicMarketOrderFeeMultiplier math.LegacyDec,
   127  	minimalProtocolFeeRate math.LegacyDec,
   128  	postOnlyModeHeightThreshold int64,
   129  ) Params {
   130  	return Params{
   131  		SpotMarketInstantListingFee:                 spotMarketInstantListingFee,
   132  		DerivativeMarketInstantListingFee:           derivativeMarketInstantListingFee,
   133  		DefaultSpotMakerFeeRate:                     defaultSpotMakerFee,
   134  		DefaultSpotTakerFeeRate:                     defaultSpotTakerFee,
   135  		DefaultDerivativeMakerFeeRate:               defaultDerivativeMakerFee,
   136  		DefaultDerivativeTakerFeeRate:               defaultDerivativeTakerFee,
   137  		DefaultInitialMarginRatio:                   defaultInitialMarginRatio,
   138  		DefaultMaintenanceMarginRatio:               defaultMaintenanceMarginRatio,
   139  		DefaultFundingInterval:                      defaultFundingInterval,
   140  		FundingMultiple:                             fundingMultiple,
   141  		RelayerFeeShareRate:                         relayerFeeShare,
   142  		DefaultHourlyFundingRateCap:                 defaultHourlyFundingRateCap,
   143  		DefaultHourlyInterestRate:                   defaultHourlyInterestRate,
   144  		MaxDerivativeOrderSideCount:                 maxDerivativeSideOrderCount,
   145  		InjRewardStakedRequirementThreshold:         injRewardStakedRequirementThreshold,
   146  		TradingRewardsVestingDuration:               tradingRewardsVestingDuration,
   147  		LiquidatorRewardShareRate:                   liquidatorRewardShareRate,
   148  		BinaryOptionsMarketInstantListingFee:        binaryOptionsMarketInstantListingFee,
   149  		AtomicMarketOrderAccessLevel:                atomicMarketOrderAccessLevel,
   150  		SpotAtomicMarketOrderFeeMultiplier:          spotAtomicMarketOrderFeeMultiplier,
   151  		DerivativeAtomicMarketOrderFeeMultiplier:    derivativeAtomicMarketOrderFeeMultiplier,
   152  		BinaryOptionsAtomicMarketOrderFeeMultiplier: binaryOptionsAtomicMarketOrderFeeMultiplier,
   153  		MinimalProtocolFeeRate:                      minimalProtocolFeeRate,
   154  		IsInstantDerivativeMarketLaunchEnabled:      false,
   155  		PostOnlyModeHeightThreshold:                 postOnlyModeHeightThreshold,
   156  	}
   157  }
   158  
   159  // ParamSetPairs returns the parameter set pairs.
   160  func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
   161  	return paramtypes.ParamSetPairs{
   162  		paramtypes.NewParamSetPair(KeySpotMarketInstantListingFee, &p.SpotMarketInstantListingFee, validateSpotMarketInstantListingFee),
   163  		paramtypes.NewParamSetPair(KeyDerivativeMarketInstantListingFee, &p.DerivativeMarketInstantListingFee, validateDerivativeMarketInstantListingFee),
   164  		paramtypes.NewParamSetPair(KeyDefaultSpotMakerFeeRate, &p.DefaultSpotMakerFeeRate, ValidateMakerFee),
   165  		paramtypes.NewParamSetPair(KeyDefaultSpotTakerFeeRate, &p.DefaultSpotTakerFeeRate, ValidateFee),
   166  		paramtypes.NewParamSetPair(KeyDefaultDerivativeMakerFeeRate, &p.DefaultDerivativeMakerFeeRate, ValidateMakerFee),
   167  		paramtypes.NewParamSetPair(KeyDefaultDerivativeTakerFeeRate, &p.DefaultDerivativeTakerFeeRate, ValidateFee),
   168  		paramtypes.NewParamSetPair(KeyDefaultInitialMarginRatio, &p.DefaultInitialMarginRatio, ValidateMarginRatio),
   169  		paramtypes.NewParamSetPair(KeyDefaultMaintenanceMarginRatio, &p.DefaultMaintenanceMarginRatio, ValidateMarginRatio),
   170  		paramtypes.NewParamSetPair(KeyDefaultFundingInterval, &p.DefaultFundingInterval, validateFundingInterval),
   171  		paramtypes.NewParamSetPair(KeyFundingMultiple, &p.FundingMultiple, validateFundingMultiple),
   172  		paramtypes.NewParamSetPair(KeyRelayerFeeShareRate, &p.RelayerFeeShareRate, ValidateFee),
   173  		paramtypes.NewParamSetPair(KeyDefaultHourlyFundingRateCap, &p.DefaultHourlyFundingRateCap, ValidateFee),
   174  		paramtypes.NewParamSetPair(KeyDefaultHourlyInterestRate, &p.DefaultHourlyInterestRate, ValidateFee),
   175  		paramtypes.NewParamSetPair(KeyMaxDerivativeOrderSideCount, &p.MaxDerivativeOrderSideCount, validateDerivativeOrderSideCount),
   176  		paramtypes.NewParamSetPair(KeyInjRewardStakedRequirementThreshold, &p.InjRewardStakedRequirementThreshold, validateInjRewardStakedRequirementThreshold),
   177  		paramtypes.NewParamSetPair(KeyTradingRewardsVestingDuration, &p.TradingRewardsVestingDuration, validateTradingRewardsVestingDuration),
   178  		paramtypes.NewParamSetPair(KeyLiquidatorRewardShareRate, &p.LiquidatorRewardShareRate, validateLiquidatorRewardShareRate),
   179  		paramtypes.NewParamSetPair(KeyBinaryOptionsMarketInstantListingFee, &p.BinaryOptionsMarketInstantListingFee, validateBinaryOptionsMarketInstantListingFee),
   180  		paramtypes.NewParamSetPair(KeyAtomicMarketOrderAccessLevel, &p.AtomicMarketOrderAccessLevel, validateAtomicMarketOrderAccessLevel),
   181  		paramtypes.NewParamSetPair(KeySpotAtomicMarketOrderFeeMultiplier, &p.SpotAtomicMarketOrderFeeMultiplier, validateAtomicMarketOrderFeeMultiplier),
   182  		paramtypes.NewParamSetPair(KeyDerivativeAtomicMarketOrderFeeMultiplier, &p.DerivativeAtomicMarketOrderFeeMultiplier, validateAtomicMarketOrderFeeMultiplier),
   183  		paramtypes.NewParamSetPair(KeyBinaryOptionsAtomicMarketOrderFeeMultiplier, &p.BinaryOptionsAtomicMarketOrderFeeMultiplier, validateAtomicMarketOrderFeeMultiplier),
   184  		paramtypes.NewParamSetPair(KeyMinimalProtocolFeeRate, &p.MinimalProtocolFeeRate, ValidateFee),
   185  		paramtypes.NewParamSetPair(KeyIsInstantDerivativeMarketLaunchEnabled, &p.IsInstantDerivativeMarketLaunchEnabled, validateBool),
   186  		paramtypes.NewParamSetPair(KeyPostOnlyModeHeightThreshold, &p.PostOnlyModeHeightThreshold, validatePostOnlyModeHeightThreshold),
   187  	}
   188  }
   189  
   190  // DefaultParams returns a default set of parameters.
   191  func DefaultParams() Params {
   192  	return Params{
   193  		SpotMarketInstantListingFee:                 sdk.NewCoin("inj", math.NewIntWithDecimal(SpotMarketInstantListingFee, 18)),
   194  		DerivativeMarketInstantListingFee:           sdk.NewCoin("inj", math.NewIntWithDecimal(DerivativeMarketInstantListingFee, 18)),
   195  		DefaultSpotMakerFeeRate:                     math.LegacyNewDecWithPrec(-1, 4), // default -0.01% maker fees
   196  		DefaultSpotTakerFeeRate:                     math.LegacyNewDecWithPrec(1, 3),  // default 0.1% taker fees
   197  		DefaultDerivativeMakerFeeRate:               math.LegacyNewDecWithPrec(-1, 4), // default -0.01% maker fees
   198  		DefaultDerivativeTakerFeeRate:               math.LegacyNewDecWithPrec(1, 3),  // default 0.1% taker fees
   199  		DefaultInitialMarginRatio:                   math.LegacyNewDecWithPrec(5, 2),  // default 5% initial margin ratio
   200  		DefaultMaintenanceMarginRatio:               math.LegacyNewDecWithPrec(2, 2),  // default 2% maintenance margin ratio
   201  		DefaultFundingInterval:                      DefaultFundingIntervalSeconds,
   202  		FundingMultiple:                             DefaultFundingMultipleSeconds,
   203  		RelayerFeeShareRate:                         math.LegacyNewDecWithPrec(40, 2),      // default 40% relayer fee share
   204  		DefaultHourlyFundingRateCap:                 math.LegacyNewDecWithPrec(625, 6),     // default 0.0625% max hourly funding rate
   205  		DefaultHourlyInterestRate:                   math.LegacyNewDecWithPrec(416666, 11), // 0.01% daily interest rate = 0.0001 / 24 = 0.00000416666
   206  		MaxDerivativeOrderSideCount:                 MaxDerivativeOrderSideCount,
   207  		InjRewardStakedRequirementThreshold:         math.NewIntWithDecimal(100, 18), // 100 INJ
   208  		TradingRewardsVestingDuration:               604800,                          // 7 days
   209  		LiquidatorRewardShareRate:                   math.LegacyNewDecWithPrec(5, 2), // 5% liquidator reward
   210  		BinaryOptionsMarketInstantListingFee:        sdk.NewCoin("inj", math.NewIntWithDecimal(BinaryOptionsMarketInstantListingFee, 18)),
   211  		AtomicMarketOrderAccessLevel:                AtomicMarketOrderAccessLevel_SmartContractsOnly,
   212  		SpotAtomicMarketOrderFeeMultiplier:          math.LegacyNewDecWithPrec(25, 1),        // default 2.5 multiplier
   213  		DerivativeAtomicMarketOrderFeeMultiplier:    math.LegacyNewDecWithPrec(25, 1),        // default 2.5 multiplier
   214  		BinaryOptionsAtomicMarketOrderFeeMultiplier: math.LegacyNewDecWithPrec(25, 1),        // default 2.5 multiplier
   215  		MinimalProtocolFeeRate:                      math.LegacyMustNewDecFromStr("0.00005"), // default 0.005% minimal fee rate
   216  		IsInstantDerivativeMarketLaunchEnabled:      false,
   217  		PostOnlyModeHeightThreshold:                 0,
   218  	}
   219  }
   220  
   221  // Validate performs basic validation on exchange parameters.
   222  func (p Params) Validate() error {
   223  	if err := validateSpotMarketInstantListingFee(p.SpotMarketInstantListingFee); err != nil {
   224  		return fmt.Errorf("spot_market_instant_listing_fee is incorrect: %w", err)
   225  	}
   226  	if err := validateDerivativeMarketInstantListingFee(p.DerivativeMarketInstantListingFee); err != nil {
   227  		return fmt.Errorf("derivative_market_instant_listing_fee is incorrect: %w", err)
   228  	}
   229  	if err := ValidateMakerFee(p.DefaultSpotMakerFeeRate); err != nil {
   230  		return fmt.Errorf("default_spot_maker_fee_rate is incorrect: %w", err)
   231  	}
   232  	if err := ValidateFee(p.DefaultSpotTakerFeeRate); err != nil {
   233  		return fmt.Errorf("default_spot_taker_fee_rate is incorrect: %w", err)
   234  	}
   235  	if err := ValidateMakerFee(p.DefaultDerivativeMakerFeeRate); err != nil {
   236  		return fmt.Errorf("default_derivative_maker_fee_rate is incorrect: %w", err)
   237  	}
   238  	if err := ValidateFee(p.DefaultDerivativeTakerFeeRate); err != nil {
   239  		return fmt.Errorf("default_derivative_taker_fee_rate is incorrect: %w", err)
   240  	}
   241  	if err := ValidateMarginRatio(p.DefaultInitialMarginRatio); err != nil {
   242  		return fmt.Errorf("default_initial_margin_ratio is incorrect: %w", err)
   243  	}
   244  	if err := ValidateMarginRatio(p.DefaultMaintenanceMarginRatio); err != nil {
   245  		return fmt.Errorf("default_maintenance_margin_ratio is incorrect: %w", err)
   246  	}
   247  	if err := validateFundingInterval(p.DefaultFundingInterval); err != nil {
   248  		return fmt.Errorf("default_funding_interval is incorrect: %w", err)
   249  	}
   250  	if err := validateFundingMultiple(p.FundingMultiple); err != nil {
   251  		return fmt.Errorf("funding_multiple is incorrect: %w", err)
   252  	}
   253  	if err := ValidateFee(p.RelayerFeeShareRate); err != nil {
   254  		return fmt.Errorf("relayer_fee_share_rate is incorrect: %w", err)
   255  	}
   256  	if err := ValidateFee(p.DefaultHourlyFundingRateCap); err != nil {
   257  		return fmt.Errorf("default_hourly_funding_rate_cap is incorrect: %w", err)
   258  	}
   259  	if err := ValidateFee(p.DefaultHourlyInterestRate); err != nil {
   260  		return fmt.Errorf("default_hourly_interest_rate is incorrect: %w", err)
   261  	}
   262  	if err := validateDerivativeOrderSideCount(p.MaxDerivativeOrderSideCount); err != nil {
   263  		return fmt.Errorf("max_derivative_order_side_count is incorrect: %w", err)
   264  	}
   265  	if err := validateInjRewardStakedRequirementThreshold(p.InjRewardStakedRequirementThreshold); err != nil {
   266  		return fmt.Errorf("inj_reward_staked_requirement_threshold is incorrect: %w", err)
   267  	}
   268  	if err := validateLiquidatorRewardShareRate(p.LiquidatorRewardShareRate); err != nil {
   269  		return fmt.Errorf("liquidator_reward_share_rate is incorrect: %w", err)
   270  	}
   271  	if err := validateBinaryOptionsMarketInstantListingFee(p.BinaryOptionsMarketInstantListingFee); err != nil {
   272  		return fmt.Errorf("binary_options_market_instant_listing_fee is incorrect: %w", err)
   273  	}
   274  	if err := validateAtomicMarketOrderAccessLevel(p.AtomicMarketOrderAccessLevel); err != nil {
   275  		return fmt.Errorf("atomic_market_order_access_level is incorrect: %w", err)
   276  	}
   277  	if err := validateAtomicMarketOrderFeeMultiplier(p.SpotAtomicMarketOrderFeeMultiplier); err != nil {
   278  		return fmt.Errorf("spot_atomic_market_order_fee_multiplier is incorrect: %w", err)
   279  	}
   280  	if err := validateAtomicMarketOrderFeeMultiplier(p.DerivativeAtomicMarketOrderFeeMultiplier); err != nil {
   281  		return fmt.Errorf("derivative_atomic_market_order_fee_multiplier is incorrect: %w", err)
   282  	}
   283  	if err := validateAtomicMarketOrderFeeMultiplier(p.BinaryOptionsAtomicMarketOrderFeeMultiplier); err != nil {
   284  		return fmt.Errorf("binary_options_atomic_market_order_fee_multiplier is incorrect: %w", err)
   285  	}
   286  	if err := ValidateFee(p.MinimalProtocolFeeRate); err != nil {
   287  		return fmt.Errorf("minimal_protocol_fee_rate is incorrect: %w", err)
   288  	}
   289  	if err := validatePostOnlyModeHeightThreshold(p.PostOnlyModeHeightThreshold); err != nil {
   290  		return fmt.Errorf("post_only_mode_height_threshold is incorrect: %w", err)
   291  	}
   292  	if err := validateAdmins(p.ExchangeAdmins); err != nil {
   293  		return fmt.Errorf("ExchangeAdmins is incorrect: %w", err)
   294  	}
   295  	return nil
   296  }
   297  
   298  func validateSpotMarketInstantListingFee(i interface{}) error {
   299  	v, ok := i.(sdk.Coin)
   300  	if !ok {
   301  		return fmt.Errorf("invalid parameter type: %T", i)
   302  	}
   303  
   304  	if !v.IsValid() || !v.Amount.IsPositive() {
   305  		return fmt.Errorf("invalid SpotMarketInstantListingFee: %T", i)
   306  	}
   307  
   308  	return nil
   309  }
   310  
   311  func validateDerivativeMarketInstantListingFee(i interface{}) error {
   312  	v, ok := i.(sdk.Coin)
   313  	if !ok {
   314  		return fmt.Errorf("invalid parameter type: %T", i)
   315  	}
   316  
   317  	if !v.IsValid() || !v.Amount.IsPositive() {
   318  		return fmt.Errorf("invalid DerivativeMarketInstantListingFee: %T", i)
   319  	}
   320  
   321  	return nil
   322  }
   323  
   324  func validateBinaryOptionsMarketInstantListingFee(i interface{}) error {
   325  	v, ok := i.(sdk.Coin)
   326  	if !ok {
   327  		return fmt.Errorf("invalid parameter type: %T", i)
   328  	}
   329  
   330  	if !v.IsValid() || !v.Amount.IsPositive() {
   331  		return fmt.Errorf("invalid BinaryOptionsMarketInstantListingFee: %T", i)
   332  	}
   333  
   334  	return nil
   335  }
   336  
   337  func ValidateFee(i interface{}) error {
   338  	v, ok := i.(math.LegacyDec)
   339  	if !ok {
   340  		return fmt.Errorf("invalid parameter type: %T", i)
   341  	}
   342  
   343  	if v.IsNil() {
   344  		return fmt.Errorf("exchange fee cannot be nil: %s", v)
   345  	}
   346  
   347  	if v.IsNegative() {
   348  		return fmt.Errorf("exchange fee cannot be negative: %s", v)
   349  	}
   350  	if v.GT(math.LegacyOneDec()) {
   351  		return fmt.Errorf("exchange fee cannot be greater than 1: %s", v)
   352  	}
   353  
   354  	return nil
   355  }
   356  
   357  func ValidateMakerFee(i interface{}) error {
   358  	v, ok := i.(math.LegacyDec)
   359  	if !ok {
   360  		return fmt.Errorf("invalid parameter type: %T", i)
   361  	}
   362  
   363  	if v.IsNil() {
   364  		return fmt.Errorf("exchange fee cannot be nil: %s", v)
   365  	}
   366  
   367  	if v.GT(math.LegacyOneDec()) {
   368  		return fmt.Errorf("exchange fee cannot be greater than 1: %s", v)
   369  	}
   370  
   371  	if v.LT(math.LegacyOneDec().Neg()) {
   372  		return fmt.Errorf("exchange fee cannot be less than -1: %s", v)
   373  	}
   374  
   375  	return nil
   376  }
   377  
   378  func ValidateHourlyFundingRateCap(i interface{}) error {
   379  	v, ok := i.(math.LegacyDec)
   380  
   381  	if !ok {
   382  		return fmt.Errorf("invalid parameter type: %T", i)
   383  	}
   384  
   385  	if v.IsNil() {
   386  		return fmt.Errorf("hourly funding rate cap cannot be nil: %s", v)
   387  	}
   388  
   389  	if v.IsNegative() {
   390  		return fmt.Errorf("hourly funding rate cap cannot be negative: %s", v)
   391  	}
   392  
   393  	if v.IsZero() {
   394  		return fmt.Errorf("hourly funding rate cap cannot be zero: %s", v)
   395  	}
   396  
   397  	if v.GT(math.LegacyNewDecWithPrec(3, 2)) {
   398  		return fmt.Errorf("hourly funding rate cap cannot be larger than 3 percent: %s", v)
   399  	}
   400  
   401  	return nil
   402  }
   403  
   404  func ValidateHourlyInterestRate(i interface{}) error {
   405  	v, ok := i.(math.LegacyDec)
   406  
   407  	if !ok {
   408  		return fmt.Errorf("invalid parameter type: %T", i)
   409  	}
   410  
   411  	if v.IsNil() {
   412  		return fmt.Errorf("hourly interest rate cannot be nil: %s", v)
   413  	}
   414  
   415  	if v.IsNegative() {
   416  		return fmt.Errorf("hourly interest rate cannot be negative: %s", v)
   417  	}
   418  
   419  	if v.GT(math.LegacyNewDecWithPrec(1, 2)) {
   420  		return fmt.Errorf("hourly interest rate cannot be larger than 1 percent: %s", v)
   421  	}
   422  
   423  	return nil
   424  }
   425  
   426  func ValidateTickSize(i interface{}) error {
   427  	v, ok := i.(math.LegacyDec)
   428  	if !ok {
   429  		return fmt.Errorf("invalid parameter type: %T", i)
   430  	}
   431  
   432  	if v.IsNil() {
   433  		return fmt.Errorf("tick size cannot be nil: %s", v)
   434  	}
   435  
   436  	if v.IsNegative() {
   437  		return fmt.Errorf("tick size cannot be negative: %s", v)
   438  	}
   439  
   440  	if v.IsZero() {
   441  		return fmt.Errorf("tick size cannot be zero: %s", v)
   442  	}
   443  
   444  	if v.GT(MaxOrderPrice) {
   445  		return fmt.Errorf("unsupported tick size amount")
   446  	}
   447  
   448  	// 1e18 scaleFactor
   449  	scaleFactor := math.LegacyNewDec(1000000000000000000)
   450  	// v can be a decimal (e.g. 1e-18) so we scale by 1e18
   451  	scaledValue := v.Mul(scaleFactor)
   452  
   453  	power := math.LegacyNewDec(1)
   454  	ten := math.LegacyNewDec(10)
   455  
   456  	// determine whether scaledValue is a power of 10
   457  	for power.LT(scaledValue) {
   458  		power = power.Mul(ten)
   459  	}
   460  
   461  	if !power.Equal(scaledValue) {
   462  		return fmt.Errorf("unsupported tick size")
   463  	}
   464  
   465  	return nil
   466  }
   467  
   468  func ValidateMinNotional(i interface{}) error {
   469  	v, ok := i.(math.LegacyDec)
   470  	if !ok {
   471  		return fmt.Errorf("invalid parameter type: %T", i)
   472  	}
   473  
   474  	if v.IsNil() {
   475  		return fmt.Errorf("min notional cannot be nil")
   476  	}
   477  
   478  	if v.IsNegative() {
   479  		return fmt.Errorf("min notional cannot be negative: %s", v)
   480  	}
   481  
   482  	return nil
   483  }
   484  
   485  func ValidateMarginRatio(i interface{}) error {
   486  	v, ok := i.(math.LegacyDec)
   487  	if !ok {
   488  		return fmt.Errorf("invalid parameter type: %T", i)
   489  	}
   490  
   491  	if v.IsNil() {
   492  		return fmt.Errorf("margin ratio cannot be nil: %s", v)
   493  	}
   494  	if v.LT(minMarginRatio) {
   495  		return fmt.Errorf("margin ratio cannot be less than minimum: %s", v)
   496  	}
   497  	if v.GTE(math.LegacyOneDec()) {
   498  		return fmt.Errorf("margin ratio cannot be greater than or equal to 1: %s", v)
   499  	}
   500  
   501  	return nil
   502  }
   503  
   504  func validateFundingInterval(i interface{}) error {
   505  	v, ok := i.(int64)
   506  	if !ok {
   507  		return fmt.Errorf("invalid parameter type: %T", i)
   508  	}
   509  
   510  	if v <= 0 {
   511  		return fmt.Errorf("fundingInterval must be positive: %d", v)
   512  	}
   513  
   514  	return nil
   515  }
   516  
   517  func validatePostOnlyModeHeightThreshold(i interface{}) error {
   518  	v, ok := i.(int64)
   519  	if !ok {
   520  		return fmt.Errorf("invalid parameter type: %T", i)
   521  	}
   522  
   523  	if v < 0 {
   524  		return fmt.Errorf("postOnlyModeHeightThreshold must be non-negative: %d", v)
   525  	}
   526  
   527  	return nil
   528  }
   529  
   530  func validateAdmins(i interface{}) error {
   531  	v, ok := i.([]string)
   532  	if !ok {
   533  		return fmt.Errorf("invalid parameter type: %T", i)
   534  	}
   535  
   536  	admins := make(map[string]struct{})
   537  
   538  	for _, admin := range v {
   539  		adminAddr, err := sdk.AccAddressFromBech32(admin)
   540  		if err != nil {
   541  			return fmt.Errorf("invalid admin address: %s", admin)
   542  		}
   543  
   544  		if _, found := admins[adminAddr.String()]; found {
   545  			return fmt.Errorf("duplicate admin: %s", admin)
   546  		}
   547  		admins[adminAddr.String()] = struct{}{}
   548  	}
   549  
   550  	return nil
   551  }
   552  
   553  func validateFundingMultiple(i interface{}) error {
   554  	v, ok := i.(int64)
   555  	if !ok {
   556  		return fmt.Errorf("invalid parameter type: %T", i)
   557  	}
   558  
   559  	if v <= 0 {
   560  		return fmt.Errorf("fundingMultiple must be positive: %d", v)
   561  	}
   562  
   563  	return nil
   564  }
   565  
   566  func validateDerivativeOrderSideCount(i interface{}) error {
   567  	v, ok := i.(uint32)
   568  	if !ok {
   569  		return fmt.Errorf("invalid parameter type: %T", i)
   570  	}
   571  
   572  	if v == 0 {
   573  		return fmt.Errorf("DerivativeOrderSideCount must be positive: %d", v)
   574  	}
   575  
   576  	return nil
   577  }
   578  
   579  func validateInjRewardStakedRequirementThreshold(i interface{}) error {
   580  	v, ok := i.(math.Int)
   581  	if !ok {
   582  		return fmt.Errorf("invalid parameter type: %T", i)
   583  	}
   584  
   585  	if v.IsZero() {
   586  		return fmt.Errorf("InjRewardStakedRequirementThreshold cannot be zero: %d", v)
   587  	}
   588  
   589  	if v.IsNegative() {
   590  		return fmt.Errorf("InjRewardStakedRequirementThreshold cannot be negative: %d", v)
   591  	}
   592  
   593  	return nil
   594  }
   595  
   596  func validateTradingRewardsVestingDuration(i interface{}) error {
   597  	v, ok := i.(int64)
   598  	if !ok {
   599  		return fmt.Errorf("invalid parameter type: %T", i)
   600  	}
   601  
   602  	if v < 0 {
   603  		return fmt.Errorf("trading rewards vesting duration must be non-negative: %d", v)
   604  	}
   605  
   606  	return nil
   607  }
   608  
   609  func validateLiquidatorRewardShareRate(i interface{}) error {
   610  	v, ok := i.(math.LegacyDec)
   611  	if !ok {
   612  		return fmt.Errorf("invalid parameter type: %T", i)
   613  	}
   614  
   615  	if v.IsNil() {
   616  		return fmt.Errorf("reward ratio cannot be nil: %s", v)
   617  	}
   618  	if v.IsNegative() {
   619  		return fmt.Errorf("reward ratio cannot be negative: %s", v)
   620  	}
   621  	if v.GT(math.LegacyOneDec()) {
   622  		return fmt.Errorf("reward ratio cannot be greater than 1: %s", v)
   623  	}
   624  
   625  	return nil
   626  }
   627  
   628  func validateAtomicMarketOrderAccessLevel(i interface{}) error {
   629  	v, ok := i.(AtomicMarketOrderAccessLevel)
   630  	if !ok {
   631  		return fmt.Errorf("invalid parameter type: %T", i)
   632  	}
   633  	if !v.IsValid() {
   634  		return fmt.Errorf("invalid AtomicMarketOrderAccessLevel value: %v", v)
   635  	}
   636  	return nil
   637  }
   638  
   639  func validateAtomicMarketOrderFeeMultiplier(i interface{}) error {
   640  	v, ok := i.(math.LegacyDec)
   641  	if !ok {
   642  		return fmt.Errorf("invalid parameter type: %T", i)
   643  	}
   644  
   645  	if v.IsNil() {
   646  		return fmt.Errorf("atomicMarketOrderFeeMultiplier cannot be nil: %s", v)
   647  	}
   648  	if v.LT(math.LegacyOneDec()) {
   649  		return fmt.Errorf("atomicMarketOrderFeeMultiplier cannot be less than one: %s", v)
   650  	}
   651  	if v.GT(MaxFeeMultiplier) {
   652  		return fmt.Errorf("atomicMarketOrderFeeMultiplier cannot be bigger than %v: %v", v, MaxFeeMultiplier)
   653  	}
   654  	return nil
   655  }
   656  
   657  func validateBool(i interface{}) error {
   658  	_, ok := i.(bool)
   659  	if !ok {
   660  		return fmt.Errorf("invalid parameter type: %T", i)
   661  	}
   662  	return nil
   663  }