/x/bep3/types/params.go

https://github.com/Kava-Labs/kava · Go · 223 lines · 168 code · 37 blank · 18 comment · 23 complexity · d47b4df44b5cac6428e3341b7fce4919 MD5 · raw file

  1. package types
  2. import (
  3. "fmt"
  4. "time"
  5. sdk "github.com/cosmos/cosmos-sdk/types"
  6. "github.com/cosmos/cosmos-sdk/x/params"
  7. tmtime "github.com/tendermint/tendermint/types/time"
  8. )
  9. const (
  10. bech32MainPrefix = "kava"
  11. )
  12. // Parameter keys
  13. var (
  14. KeyAssetParams = []byte("AssetParams")
  15. DefaultBnbDeputyFixedFee sdk.Int = sdk.NewInt(1000) // 0.00001 BNB
  16. DefaultMinAmount sdk.Int = sdk.ZeroInt()
  17. DefaultMaxAmount sdk.Int = sdk.NewInt(1000000000000) // 10,000 BNB
  18. DefaultMinBlockLock uint64 = 220
  19. DefaultMaxBlockLock uint64 = 270
  20. DefaultPreviousBlockTime = tmtime.Canonical(time.Unix(1, 0))
  21. )
  22. // Params governance parameters for bep3 module
  23. type Params struct {
  24. AssetParams AssetParams `json:"asset_params" yaml:"asset_params"`
  25. }
  26. // String implements fmt.Stringer
  27. func (p Params) String() string {
  28. return fmt.Sprintf(`Params:
  29. AssetParams: %s`,
  30. p.AssetParams)
  31. }
  32. // NewParams returns a new params object
  33. func NewParams(ap AssetParams,
  34. ) Params {
  35. return Params{
  36. AssetParams: ap,
  37. }
  38. }
  39. // DefaultParams returns default params for bep3 module
  40. func DefaultParams() Params {
  41. return NewParams(AssetParams{})
  42. }
  43. // AssetParam parameters that must be specified for each bep3 asset
  44. type AssetParam struct {
  45. Denom string `json:"denom" yaml:"denom"` // name of the asset
  46. CoinID int `json:"coin_id" yaml:"coin_id"` // SLIP-0044 registered coin type - see https://github.com/satoshilabs/slips/blob/master/slip-0044.md
  47. SupplyLimit SupplyLimit `json:"supply_limit" yaml:"supply_limit"` // asset supply limit
  48. Active bool `json:"active" yaml:"active"` // denotes if asset is available or paused
  49. DeputyAddress sdk.AccAddress `json:"deputy_address" yaml:"deputy_address"` // the address of the relayer process
  50. FixedFee sdk.Int `json:"fixed_fee" yaml:"fixed_fee"` // the fixed fee charged by the relayer process for outgoing swaps
  51. MinSwapAmount sdk.Int `json:"min_swap_amount" yaml:"min_swap_amount"` // Minimum swap amount
  52. MaxSwapAmount sdk.Int `json:"max_swap_amount" yaml:"max_swap_amount"` // Maximum swap amount
  53. MinBlockLock uint64 `json:"min_block_lock" yaml:"min_block_lock"` // Minimum swap block lock
  54. MaxBlockLock uint64 `json:"max_block_lock" yaml:"max_block_lock"` // Maximum swap block lock
  55. }
  56. // NewAssetParam returns a new AssetParam
  57. func NewAssetParam(
  58. denom string, coinID int, limit SupplyLimit, active bool,
  59. deputyAddr sdk.AccAddress, fixedFee sdk.Int, minSwapAmount sdk.Int,
  60. maxSwapAmount sdk.Int, minBlockLock uint64, maxBlockLock uint64,
  61. ) AssetParam {
  62. return AssetParam{
  63. Denom: denom,
  64. CoinID: coinID,
  65. SupplyLimit: limit,
  66. Active: active,
  67. DeputyAddress: deputyAddr,
  68. FixedFee: fixedFee,
  69. MinSwapAmount: minSwapAmount,
  70. MaxSwapAmount: maxSwapAmount,
  71. MinBlockLock: minBlockLock,
  72. MaxBlockLock: maxBlockLock,
  73. }
  74. }
  75. // String implements fmt.Stringer
  76. func (ap AssetParam) String() string {
  77. return fmt.Sprintf(`Asset:
  78. Denom: %s
  79. Coin ID: %d
  80. Limit: %s
  81. Active: %t
  82. Deputy Address: %s
  83. Fixed Fee: %s
  84. Min Swap Amount: %s
  85. Max Swap Amount: %s
  86. Min Block Lock: %d
  87. Max Block Lock: %d`,
  88. ap.Denom, ap.CoinID, ap.SupplyLimit, ap.Active, ap.DeputyAddress, ap.FixedFee,
  89. ap.MinSwapAmount, ap.MaxSwapAmount, ap.MinBlockLock, ap.MaxBlockLock)
  90. }
  91. // AssetParams array of AssetParam
  92. type AssetParams []AssetParam
  93. // String implements fmt.Stringer
  94. func (aps AssetParams) String() string {
  95. out := "Asset Params\n"
  96. for _, ap := range aps {
  97. out += fmt.Sprintf("%s\n", ap)
  98. }
  99. return out
  100. }
  101. // SupplyLimit parameters that control the absolute and time-based limits for an assets's supply
  102. type SupplyLimit struct {
  103. Limit sdk.Int `json:"limit" yaml:"limit"` // the absolute supply limit for an asset
  104. TimeLimited bool `json:"time_limited" yaml:"time_limited"` // boolean for if the supply is also limited by time
  105. TimePeriod time.Duration `json:"time_period" yaml:"time_period"` // the duration for which the supply time limit applies
  106. TimeBasedLimit sdk.Int `json:"time_based_limit" yaml:"time_based_limit"` // the supply limit for an asset for each time period
  107. }
  108. // String implements fmt.Stringer
  109. func (sl SupplyLimit) String() string {
  110. return fmt.Sprintf(`%s
  111. %t
  112. %s
  113. %s
  114. `, sl.Limit, sl.TimeLimited, sl.TimePeriod, sl.TimeBasedLimit)
  115. }
  116. // Equals returns true if two supply limits are equal
  117. func (sl SupplyLimit) Equals(sl2 SupplyLimit) bool {
  118. return sl.Limit.Equal(sl2.Limit) && sl.TimeLimited == sl2.TimeLimited && sl.TimePeriod == sl2.TimePeriod && sl.TimeBasedLimit.Equal(sl2.TimeBasedLimit)
  119. }
  120. // ParamKeyTable Key declaration for parameters
  121. func ParamKeyTable() params.KeyTable {
  122. return params.NewKeyTable().RegisterParamSet(&Params{})
  123. }
  124. // ParamSetPairs implements the ParamSet interface and returns all the key/value pairs
  125. // pairs of bep3 module's parameters.
  126. // nolint
  127. func (p *Params) ParamSetPairs() params.ParamSetPairs {
  128. return params.ParamSetPairs{
  129. params.NewParamSetPair(KeyAssetParams, &p.AssetParams, validateAssetParams),
  130. }
  131. }
  132. // Validate ensure that params have valid values
  133. func (p Params) Validate() error {
  134. return validateAssetParams(p.AssetParams)
  135. }
  136. func validateAssetParams(i interface{}) error {
  137. assetParams, ok := i.(AssetParams)
  138. if !ok {
  139. return fmt.Errorf("invalid parameter type: %T", i)
  140. }
  141. coinDenoms := make(map[string]bool)
  142. for _, asset := range assetParams {
  143. if err := sdk.ValidateDenom(asset.Denom); err != nil {
  144. return fmt.Errorf(fmt.Sprintf("asset denom invalid: %s", asset.Denom))
  145. }
  146. if asset.CoinID < 0 {
  147. return fmt.Errorf(fmt.Sprintf("asset %s coin id must be a non negative integer", asset.Denom))
  148. }
  149. if asset.SupplyLimit.Limit.IsNegative() {
  150. return fmt.Errorf(fmt.Sprintf("asset %s has invalid (negative) supply limit: %s", asset.Denom, asset.SupplyLimit.Limit))
  151. }
  152. if asset.SupplyLimit.TimeBasedLimit.IsNegative() {
  153. return fmt.Errorf(fmt.Sprintf("asset %s has invalid (negative) supply time limit: %s", asset.Denom, asset.SupplyLimit.TimeBasedLimit))
  154. }
  155. if asset.SupplyLimit.TimeBasedLimit.GT(asset.SupplyLimit.Limit) {
  156. return fmt.Errorf(fmt.Sprintf("asset %s cannot have supply time limit > supply limit: %s>%s", asset.Denom, asset.SupplyLimit.TimeBasedLimit, asset.SupplyLimit.Limit))
  157. }
  158. _, found := coinDenoms[asset.Denom]
  159. if found {
  160. return fmt.Errorf(fmt.Sprintf("asset %s cannot have duplicate denom", asset.Denom))
  161. }
  162. coinDenoms[asset.Denom] = true
  163. if asset.DeputyAddress.Empty() {
  164. return fmt.Errorf("deputy address cannot be empty for %s", asset.Denom)
  165. }
  166. if len(asset.DeputyAddress.Bytes()) != sdk.AddrLen {
  167. return fmt.Errorf("%s deputy address invalid bytes length got %d, want %d", asset.Denom, len(asset.DeputyAddress.Bytes()), sdk.AddrLen)
  168. }
  169. if asset.FixedFee.IsNegative() {
  170. return fmt.Errorf("asset %s cannot have a negative fixed fee %s", asset.Denom, asset.FixedFee)
  171. }
  172. if asset.MinBlockLock > asset.MaxBlockLock {
  173. return fmt.Errorf("asset %s has minimum block lock > maximum block lock %d > %d", asset.Denom, asset.MinBlockLock, asset.MaxBlockLock)
  174. }
  175. if !asset.MinSwapAmount.IsPositive() {
  176. return fmt.Errorf(fmt.Sprintf("asset %s must have a positive minimum swap amount, got %s", asset.Denom, asset.MinSwapAmount))
  177. }
  178. if !asset.MaxSwapAmount.IsPositive() {
  179. return fmt.Errorf(fmt.Sprintf("asset %s must have a positive maximum swap amount, got %s", asset.Denom, asset.MaxSwapAmount))
  180. }
  181. if asset.MinSwapAmount.GT(asset.MaxSwapAmount) {
  182. return fmt.Errorf("asset %s has minimum swap amount > maximum swap amount %s > %s", asset.Denom, asset.MinSwapAmount, asset.MaxSwapAmount)
  183. }
  184. }
  185. return nil
  186. }