diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index a09fe0492..d65190f96 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -55119,6 +55119,12 @@ definitions: min_stability_spread: type: string format: byte + max_supply_coin: + type: string + format: byte + percentage_supply_max_descending: + type: string + format: byte description: Params defines the parameters for the market module. terra.market.v1beta1.QueryParamsResponse: type: object diff --git a/contrib/terra-operator/entrypoint.sh b/contrib/terra-operator/entrypoint.sh index 7ddbd3eeb..8ad440161 100755 --- a/contrib/terra-operator/entrypoint.sh +++ b/contrib/terra-operator/entrypoint.sh @@ -4,7 +4,7 @@ DATADIR="${DATADIR:-/terra/.terra/data}" MONIKER="${MONIKER:-docker-node}" ENABLE_LCD="${ENABLE_LCD:-true}" -MINIMUM_GAS_PRICES=${MINIMUM_GAS_PRICES-0.01133uluna,0.15uusd,0.104938usdr,169.77ukrw,428.571umnt,0.125ueur,0.98ucny,16.37ujpy,0.11ugbp,10.88uinr,0.19ucad,0.14uchf,0.19uaud,0.2usgd,4.62uthb,1.25usek,1.25unok,0.9udkk,2180.0uidr,7.6uphp,1.17uhkd} +MINIMUM_GAS_PRICES=${MINIMUM_GAS_PRICES-0.01133uluna,0.15uusd,0.104938usdr,169.77ukrw,428.571umnt,0.125ueur,0.98ucny,16.37ujpy,0.11ugbp,10.88uinr,0.19ucad,0.14uchf,0.19uaud,0.2usgd,4.62uthb,1.25usek,1.25unok,0.9udkk,2180.0uidr,7.6uphp,1.17uhkd,0.01uivcs} SNAPSHOT_NAME="${SNAPSHOT_NAME}" SNAPSHOT_BASE_URL="${SNAPSHOT_BASE_URL:-https://getsfo.quicksync.io}" diff --git a/proto/terra/market/v1beta1/market.proto b/proto/terra/market/v1beta1/market.proto index 756b89197..478c08712 100644 --- a/proto/terra/market/v1beta1/market.proto +++ b/proto/terra/market/v1beta1/market.proto @@ -21,4 +21,14 @@ message Params { (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; + bytes max_supply_coin = 4 [ + (gogoproto.moretags) = "yaml:\"max_supply_coin\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Coin", + (gogoproto.nullable) = false + ]; + bytes percentage_supply_max_descending = 5 [ + (gogoproto.moretags) = "yaml:\"percentage_supply_max_descending\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; } diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index a757fd207..3f6a8a69f 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -77,6 +77,31 @@ func (k Keeper) SetTerraPoolDelta(ctx sdk.Context, delta sdk.Dec) { store.Set(types.TerraPoolDeltaKey, bz) } +// GetTerraPoolDelta returns the gap between the TerraPool and the TerraBasePool +func (k Keeper) GetSupplyMaxDescending(ctx sdk.Context, key []byte) sdk.Int { + store := ctx.KVStore(k.storeKey) + bz := store.Get(key) + if bz == nil { + return sdk.ZeroInt() + } + + dp := sdk.IntProto{} + k.cdc.MustUnmarshal(bz, &dp) + return dp.Int +} + +// SetTerraPoolDelta updates TerraPoolDelta which is gap between the TerraPool and the BasePool +func (k Keeper) SetSupplyMaxDescending(ctx sdk.Context, key []byte, delta sdk.Int) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(&sdk.IntProto{Int: delta}) + store.Set(key, bz) +} + +func (k Keeper) HasSupplyMaxDescending(ctx sdk.Context, key []byte) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(key) +} + // ReplenishPools replenishes each pool(Terra,Luna) to BasePool func (k Keeper) ReplenishPools(ctx sdk.Context) { poolDelta := k.GetTerraPoolDelta(ctx) diff --git a/x/market/keeper/msg_server.go b/x/market/keeper/msg_server.go index 550c8c7b8..0c8e6e3ee 100644 --- a/x/market/keeper/msg_server.go +++ b/x/market/keeper/msg_server.go @@ -7,6 +7,7 @@ import ( "github.com/classic-terra/core/v2/x/market/types" oracletypes "github.com/classic-terra/core/v2/x/oracle/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) type msgServer struct { @@ -67,6 +68,10 @@ func (k msgServer) handleSwapRequest(ctx sdk.Context, return nil, err } + errSup := k.ValidateSupplyMaximum(ctx, sdk.NewDecCoin(swapDecCoin.Denom, swapDecCoin.Amount.TruncateInt())) + if errSup != nil { + return nil, errSup + } // Charge a spread if applicable; the spread is burned var feeDecCoin sdk.DecCoin if spread.IsPositive() { @@ -97,6 +102,20 @@ func (k msgServer) handleSwapRequest(ctx sdk.Context, return nil, err } + for _, offerCoin := range offerCoins { + amountP := sdk.NewDec(offerCoin.Amount.Int64()).Mul(k.PercentageSupplyMaxDescending(ctx)) + supplyMaxDescending := k.GetSupplyMaxDescending(ctx, []byte("SupplyMaxDescending"+offerCoin.Denom)) + if !k.HasSupplyMaxDescending(ctx, []byte("SupplyMaxDescending"+offerCoin.Denom)) { + ok, amount := k.isExists(ctx, offerCoin.Denom, k.GetMaxSupplyCoin(ctx)) + if ok { + supplyMaxDescending = amount + } else { + return nil, sdkerrors.Wrap(types.ErrZeroSwapCoin, "Need to declare the maximum limit of supply "+offerCoin.Denom) + } + } + k.SetSupplyMaxDescending(ctx, []byte("SupplyMaxDescending"+offerCoin.Denom), supplyMaxDescending.Sub(amountP.TruncateInt())) + + } // Mint asked coins and credit Trader's account swapCoin, decimalCoin := swapDecCoin.TruncateDecimal() @@ -150,3 +169,38 @@ func (k msgServer) handleSwapRequest(ctx sdk.Context, SwapFee: feeCoin, }, nil } + +func (k Keeper) ValidateSupplyMaximum(ctx sdk.Context, coin sdk.DecCoin) error { + ok, amount := k.isExists(ctx, coin.Denom, k.GetMaxSupplyCoin(ctx)) + + totalSupply := k.BankKeeper.GetSupply(ctx, coin.Denom) + if ok { + if totalSupply.Amount.Add(coin.Amount.TruncateInt()).GT(amount) { + return sdkerrors.Wrap(types.ErrZeroSwapCoin, "The value to be minted exceeded the maximum supply value "+amount.String()+coin.Denom) + } + } else { + return sdkerrors.Wrap(types.ErrZeroSwapCoin, "maximum supply not configured for currency "+coin.Denom) + } + + return nil +} + +func (k Keeper) isExists(ctx sdk.Context, demom string, coins sdk.Coins) (result bool, amount sdk.Int) { + result = false + for _, coin := range coins { + if coin.Denom == demom { + amount = coin.Amount + if !k.HasSupplyMaxDescending(ctx, []byte("SupplyMaxDescending"+demom)) { + k.SetSupplyMaxDescending(ctx, []byte("SupplyMaxDescending"+demom), coin.Amount) + } else { + supplyMaxDescending := k.GetSupplyMaxDescending(ctx, []byte("SupplyMaxDescending"+demom)) + if coin.Amount.GT(supplyMaxDescending) { + amount = supplyMaxDescending + } + } + result = true + break + } + } + return result, amount +} diff --git a/x/market/keeper/params.go b/x/market/keeper/params.go index ccfe60025..e3b84a303 100644 --- a/x/market/keeper/params.go +++ b/x/market/keeper/params.go @@ -25,6 +25,20 @@ func (k Keeper) PoolRecoveryPeriod(ctx sdk.Context) (res uint64) { return } +func (k Keeper) GetMaxSupplyCoin(ctx sdk.Context) (res sdk.Coins) { + k.paramSpace.Get(ctx, types.KeyMaxSupplyCoin, &res) + return +} + +func (k Keeper) SetMaxSupplyCoin(ctx sdk.Context, maxSupplyCoin sdk.Coins) { + k.paramSpace.Set(ctx, types.KeyMaxSupplyCoin, maxSupplyCoin) +} + +func (k Keeper) PercentageSupplyMaxDescending(ctx sdk.Context) (res sdk.Dec) { + k.paramSpace.Get(ctx, types.KeyPercentageSupplyMaxDescending, &res) + return +} + // GetParams returns the total set of market parameters. func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { k.paramSpace.GetParamSet(ctx, ¶ms) diff --git a/x/market/keeper/swap.go b/x/market/keeper/swap.go index 82c2c78c8..72b85f4a9 100644 --- a/x/market/keeper/swap.go +++ b/x/market/keeper/swap.go @@ -54,7 +54,6 @@ func (k Keeper) ComputeSwap(ctx sdk.Context, offerCoin sdk.Coin, askDenom string if offerCoin.Denom == askDenom { return sdk.DecCoin{}, sdk.ZeroDec(), sdkerrors.Wrap(types.ErrRecursiveSwap, askDenom) } - // Swap offer coin to base denom for simplicity of swap process baseOfferDecCoin, err := k.ComputeInternalSwap(ctx, sdk.NewDecCoinFromCoin(offerCoin), core.MicroSDRDenom) if err != nil { @@ -180,5 +179,6 @@ func (k Keeper) simulateSwap(ctx sdk.Context, offerCoin sdk.Coin, askDenom strin } retCoin, _ := swapCoin.TruncateDecimal() + return retCoin, nil } diff --git a/x/market/legacy/v04/types.go b/x/market/legacy/v04/types.go index 571a40dff..f8adba9d7 100644 --- a/x/market/legacy/v04/types.go +++ b/x/market/legacy/v04/types.go @@ -13,9 +13,11 @@ const ( type ( // Params market parameters Params struct { - BasePool sdk.Dec `json:"base_pool" yaml:"base_pool"` - PoolRecoveryPeriod int64 `json:"pool_recovery_period" yaml:"pool_recovery_period"` - MinStabilitySpread sdk.Dec `json:"min_spread" yaml:"min_spread"` + BasePool sdk.Dec `json:"base_pool" yaml:"base_pool"` + PoolRecoveryPeriod int64 `json:"pool_recovery_period" yaml:"pool_recovery_period"` + MinStabilitySpread sdk.Dec `json:"min_spread" yaml:"min_spread"` + MaxSupplyCoin sdk.Coins `json:"max_supply_coin" yaml:"max_supply_coin"` + PercentageSupplyMaxDescending sdk.Dec `json:"percentage_supply_max_descending" yaml:"percentage_supply_max_descending"` } // GenesisState is the struct representation of the export genesis diff --git a/x/market/legacy/v05/migrate.go b/x/market/legacy/v05/migrate.go index 60957c28f..94dabeb6a 100644 --- a/x/market/legacy/v05/migrate.go +++ b/x/market/legacy/v05/migrate.go @@ -18,9 +18,11 @@ func Migrate( return &v05market.GenesisState{ TerraPoolDelta: sdk.ZeroDec(), Params: v05market.Params{ - BasePool: marketGenState.Params.BasePool, - PoolRecoveryPeriod: uint64(marketGenState.Params.PoolRecoveryPeriod), - MinStabilitySpread: marketGenState.Params.MinStabilitySpread, + BasePool: marketGenState.Params.BasePool, + PoolRecoveryPeriod: uint64(marketGenState.Params.PoolRecoveryPeriod), + MinStabilitySpread: marketGenState.Params.MinStabilitySpread, + MaxSupplyCoin: marketGenState.Params.MaxSupplyCoin, + PercentageSupplyMaxDescending: marketGenState.Params.PercentageSupplyMaxDescending, }, } } diff --git a/x/market/legacy/v05/migrate_test.go b/x/market/legacy/v05/migrate_test.go index e85a09649..5eb32e891 100644 --- a/x/market/legacy/v05/migrate_test.go +++ b/x/market/legacy/v05/migrate_test.go @@ -18,7 +18,6 @@ import ( func TestMigrate(t *testing.T) { sdk.GetConfig().SetBech32PrefixForAccount(core.Bech32PrefixAccAddr, core.Bech32PrefixAccPub) - encodingConfig := app.MakeEncodingConfig() clientCtx := client.Context{}. WithInterfaceRegistry(encodingConfig.InterfaceRegistry). @@ -31,7 +30,31 @@ func TestMigrate(t *testing.T) { Params: v04market.Params{ BasePool: sdk.NewDec(1000000), PoolRecoveryPeriod: int64(10000), - MinStabilitySpread: sdk.NewDecWithPrec(2, 2), + MinStabilitySpread: sdk.NewDecWithPrec(2, 2), // ATTENTION: The list of modes must be in alphabetical order, otherwise an error occurs in validateMaxSupplyCoin => !v.IsValid() + MaxSupplyCoin: sdk.Coins{ + {Denom: "uaud", Amount: sdk.NewInt(500000000000)}, + {Denom: "ucad", Amount: sdk.NewInt(500000000000)}, + {Denom: "uchf", Amount: sdk.NewInt(500000000000)}, + {Denom: "ucny", Amount: sdk.NewInt(500000000000)}, + {Denom: "udkk", Amount: sdk.NewInt(500000000000)}, + {Denom: "ueur", Amount: sdk.NewInt(500000000000)}, + {Denom: "ugbp", Amount: sdk.NewInt(500000000000)}, + {Denom: "uhkd", Amount: sdk.NewInt(500000000000)}, + {Denom: "uidr", Amount: sdk.NewInt(500000000000)}, + {Denom: "uinr", Amount: sdk.NewInt(500000000000)}, + {Denom: "ujpy", Amount: sdk.NewInt(500000000000)}, + {Denom: "ukrw", Amount: sdk.NewInt(500000000000)}, + {Denom: "uluna", Amount: sdk.NewInt(1000000000000)}, + {Denom: "umnt", Amount: sdk.NewInt(500000000000)}, + {Denom: "unok", Amount: sdk.NewInt(500000000000)}, + {Denom: "uphp", Amount: sdk.NewInt(500000000000)}, + {Denom: "usdr", Amount: sdk.NewInt(500000000000)}, + {Denom: "usek", Amount: sdk.NewInt(500000000000)}, + {Denom: "usgd", Amount: sdk.NewInt(500000000000)}, + {Denom: "uthb", Amount: sdk.NewInt(500000000000)}, + {Denom: "uusd", Amount: sdk.NewInt(500000000000)}, + }, + PercentageSupplyMaxDescending: sdk.NewDecWithPrec(30, 2), // 30% }, } @@ -50,13 +73,100 @@ func TestMigrate(t *testing.T) { // Make sure about: // - BasePool to Mint & Burn pool expected := `{ - "params": { - "base_pool": "1000000.000000000000000000", - "min_stability_spread": "0.020000000000000000", - "pool_recovery_period": "10000" - }, - "terra_pool_delta": "0.000000000000000000" -}` + "params": { + "base_pool": "1000000.000000000000000000", + "min_stability_spread": "0.020000000000000000", + "pool_recovery_period": "10000", + "max_supply_coin": [ + { + "denom": "uaud", + "amount": "500000000000" + }, + { + "denom": "ucad", + "amount": "500000000000" + }, + { + "denom": "uchf", + "amount": "500000000000" + }, + { + "denom": "ucny", + "amount": "500000000000" + }, + { + "denom": "udkk", + "amount": "500000000000" + }, + { + "denom": "ueur", + "amount": "500000000000" + }, + { + "denom": "ugbp", + "amount": "500000000000" + }, + { + "denom": "uhkd", + "amount": "500000000000" + }, + { + "denom": "uidr", + "amount": "500000000000" + }, + { + "denom": "uinr", + "amount": "500000000000" + }, + { + "denom": "ujpy", + "amount": "500000000000" + }, + { + "denom": "ukrw", + "amount": "500000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000" + }, + { + "denom": "umnt", + "amount": "500000000000" + }, + { + "denom": "unok", + "amount": "500000000000" + }, + { + "denom": "uphp", + "amount": "500000000000" + }, + { + "denom": "usdr", + "amount": "500000000000" + }, + { + "denom": "usek", + "amount": "500000000000" + }, + { + "denom": "usgd", + "amount": "500000000000" + }, + { + "denom": "uthb", + "amount": "500000000000" + }, + { + "denom": "uusd", + "amount": "500000000000" + } + ], + "percentage_supply_max_descending": "0.300000000000000000" + }, + "terra_pool_delta": "0.000000000000000000" + }` assert.JSONEq(t, expected, string(indentedBz)) } diff --git a/x/market/types/expected_keepers.go b/x/market/types/expected_keepers.go index 2ef431d6b..96a7cf4d3 100644 --- a/x/market/types/expected_keepers.go +++ b/x/market/types/expected_keepers.go @@ -17,7 +17,7 @@ type BankKeeper interface { SendCoinsFromModuleToModule(ctx sdk.Context, senderModule string, recipientModule string, amt sdk.Coins) error SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error - + GetSupply(ctx sdk.Context, denom string) sdk.Coin BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error MintCoins(ctx sdk.Context, name string, amt sdk.Coins) error diff --git a/x/market/types/market.pb.go b/x/market/types/market.pb.go index 53f7a0481..9a36f9656 100644 --- a/x/market/types/market.pb.go +++ b/x/market/types/market.pb.go @@ -12,6 +12,8 @@ import ( github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/gogo/protobuf/proto" + + ) // Reference imports to suppress errors if they are not otherwise used. @@ -32,8 +34,12 @@ type Params struct { BasePool github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=base_pool,json=basePool,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"base_pool" yaml:"base_pool"` PoolRecoveryPeriod uint64 `protobuf:"varint,2,opt,name=pool_recovery_period,json=poolRecoveryPeriod,proto3" json:"pool_recovery_period,omitempty" yaml:"pool_recovery_period"` MinStabilitySpread github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=min_stability_spread,json=minStabilitySpread,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"min_stability_spread" yaml:"min_stability_spread"` + MaxSupplyCoin github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,4,opt,name=max_supply_coin,json=maxSupplyCoin,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Coin" json:"max_supply_coin" yaml:"max_supply_coin"` + PercentageSupplyMaxDescending github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,8,opt,name=percentage_supply_max_descending,json=percentageSupplyMaxDescending,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"percentage_supply_max_descending" yaml:"percentage_supply_max_descending"` } + + func (m *Params) Reset() { *m = Params{} } func (*Params) ProtoMessage() {} func (*Params) Descriptor() ([]byte, []int) { @@ -137,6 +143,9 @@ func (this *Params) Equal(that interface{}) bool { if !this.MinStabilitySpread.Equal(that1.MinStabilitySpread) { return false } + if !this.PercentageSupplyMaxDescending.Equal(that1.PercentageSupplyMaxDescending) { + return false + } return true } @@ -170,6 +179,8 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x1a + + if m.PoolRecoveryPeriod != 0 { i = encodeVarintMarket(dAtA, i, uint64(m.PoolRecoveryPeriod)) i-- @@ -183,6 +194,14 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i = encodeVarintMarket(dAtA, i, uint64(size)) } + { + size := m.PercentageSupplyMaxDescending.Size() + i -= size + if _, err := m.PercentageSupplyMaxDescending.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintMarket(dAtA, i, uint64(size)) + } i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -213,6 +232,8 @@ func (m *Params) Size() (n int) { } l = m.MinStabilitySpread.Size() n += 1 + l + sovMarket(uint64(l)) + l = m.PercentageSupplyMaxDescending.Size() + n += 1 + l + sovMarket(uint64(l)) return n } @@ -338,6 +359,39 @@ func (m *Params) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PercentageSupplyMaxDescending", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMarket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMarket + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMarket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.PercentageSupplyMaxDescending.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMarket(dAtA[iNdEx:]) diff --git a/x/market/types/params.go b/x/market/types/params.go index 5f3ddbe12..54c2df82d 100644 --- a/x/market/types/params.go +++ b/x/market/types/params.go @@ -18,14 +18,41 @@ var ( // The period required to recover BasePool KeyPoolRecoveryPeriod = []byte("PoolRecoveryPeriod") // Min spread - KeyMinStabilitySpread = []byte("MinStabilitySpread") + KeyMinStabilitySpread = []byte("MinStabilitySpread") + KeyMaxSupplyCoin = []byte("MaxSupplyCoin") + KeyPercentageSupplyMaxDescending = []byte("PercentageSupplyMaxDescending") ) // Default parameter values var ( DefaultBasePool = sdk.NewDec(1000000 * core.MicroUnit) // 1000,000sdr = 1000,000,000,000usdr DefaultPoolRecoveryPeriod = core.BlocksPerDay // 14,400 - DefaultMinStabilitySpread = sdk.NewDecWithPrec(2, 2) // 2% + DefaultMinStabilitySpread = sdk.NewDecWithPrec(2, 2) + // ATTENTION: The list of modes must be in alphabetical order, otherwise an error occurs in validateMaxSupplyCoin => !v.IsValid() + DefaultMaxSupplyCoin = sdk.Coins{ + {Denom: "uaud", Amount: sdk.NewInt(500000000000)}, + {Denom: "ucad", Amount: sdk.NewInt(500000000000)}, + {Denom: "uchf", Amount: sdk.NewInt(500000000000)}, + {Denom: "ucny", Amount: sdk.NewInt(500000000000)}, + {Denom: "udkk", Amount: sdk.NewInt(500000000000)}, + {Denom: "ueur", Amount: sdk.NewInt(500000000000)}, + {Denom: "ugbp", Amount: sdk.NewInt(500000000000)}, + {Denom: "uhkd", Amount: sdk.NewInt(500000000000)}, + {Denom: "uidr", Amount: sdk.NewInt(500000000000)}, + {Denom: "uinr", Amount: sdk.NewInt(500000000000)}, + {Denom: "ujpy", Amount: sdk.NewInt(500000000000)}, + {Denom: "ukrw", Amount: sdk.NewInt(500000000000)}, + {Denom: "uluna", Amount: sdk.NewInt(1000000000000)}, + {Denom: "umnt", Amount: sdk.NewInt(500000000000)}, + {Denom: "unok", Amount: sdk.NewInt(500000000000)}, + {Denom: "uphp", Amount: sdk.NewInt(500000000000)}, + {Denom: "usdr", Amount: sdk.NewInt(500000000000)}, + {Denom: "usek", Amount: sdk.NewInt(500000000000)}, + {Denom: "usgd", Amount: sdk.NewInt(500000000000)}, + {Denom: "uthb", Amount: sdk.NewInt(500000000000)}, + {Denom: "uusd", Amount: sdk.NewInt(500000000000)}, + } + DefaultPercentageSupplyMaxDescending = sdk.NewDecWithPrec(30, 2) // 30% ) var _ paramstypes.ParamSet = &Params{} @@ -33,9 +60,11 @@ var _ paramstypes.ParamSet = &Params{} // DefaultParams creates default market module parameters func DefaultParams() Params { return Params{ - BasePool: DefaultBasePool, - PoolRecoveryPeriod: DefaultPoolRecoveryPeriod, - MinStabilitySpread: DefaultMinStabilitySpread, + BasePool: DefaultBasePool, + PoolRecoveryPeriod: DefaultPoolRecoveryPeriod, + MinStabilitySpread: DefaultMinStabilitySpread, + MaxSupplyCoin: DefaultMaxSupplyCoin, + PercentageSupplyMaxDescending: DefaultPercentageSupplyMaxDescending, } } @@ -57,6 +86,8 @@ func (p *Params) ParamSetPairs() paramstypes.ParamSetPairs { paramstypes.NewParamSetPair(KeyBasePool, &p.BasePool, validateBasePool), paramstypes.NewParamSetPair(KeyPoolRecoveryPeriod, &p.PoolRecoveryPeriod, validatePoolRecoveryPeriod), paramstypes.NewParamSetPair(KeyMinStabilitySpread, &p.MinStabilitySpread, validateMinStabilitySpread), + paramstypes.NewParamSetPair(KeyMaxSupplyCoin, &p.MaxSupplyCoin, validateMaxSupplyCoin), + paramstypes.NewParamSetPair(KeyPercentageSupplyMaxDescending, &p.PercentageSupplyMaxDescending, validatePercentageSupplyMaxDescending), } } @@ -71,7 +102,12 @@ func (p Params) Validate() error { if p.MinStabilitySpread.IsNegative() || p.MinStabilitySpread.GT(sdk.OneDec()) { return fmt.Errorf("market minimum stability spead should be a value between [0,1], is %s", p.MinStabilitySpread) } - + if len(p.MaxSupplyCoin) == 0 { + return fmt.Errorf("max supplay cannot be empty %s", p.MaxSupplyCoin) + } + if p.PercentageSupplyMaxDescending.IsNegative() { + return fmt.Errorf("mint base pool should be positive or zero, is %s", p.PercentageSupplyMaxDescending) + } return nil } @@ -117,3 +153,28 @@ func validateMinStabilitySpread(i interface{}) error { return nil } + +func validateMaxSupplyCoin(i interface{}) error { + v, ok := i.(sdk.Coins) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + if !v.IsValid() { + return fmt.Errorf("invalid max supply: %s", v) + } + + return nil +} + +func validatePercentageSupplyMaxDescending(i interface{}) error { + v, ok := i.(sdk.Dec) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v.IsNegative() { + return fmt.Errorf("mint Percentage Supply Max Descending must be positive or zero: %s", v) + } + + return nil +}