From dd1d248be2b7cfd43bcc3b2c8b15afeb4ce242b1 Mon Sep 17 00:00:00 2001 From: Denali Marsh Date: Wed, 13 May 2020 16:39:29 -0700 Subject: [PATCH] [R4R] Add BnbDeputyFixedFee param to BEP3 module (#511) * generate length 32 random bytes * fix test * implement BnbDeputyFixedFee param * clean up for PR * update deputy address * remove impossible check * move comment --- .../genesis_examples/wip_genesis.json | 3 +- x/bep3/genesis_test.go | 9 ++ x/bep3/keeper/integration_test.go | 9 +- x/bep3/keeper/params.go | 6 ++ x/bep3/keeper/params_test.go | 8 ++ x/bep3/keeper/swap.go | 6 +- x/bep3/keeper/swap_test.go | 43 ++++++--- x/bep3/simulation/genesis.go | 17 +++- x/bep3/simulation/operations.go | 5 +- x/bep3/simulation/params.go | 14 ++- x/bep3/spec/02_state.md | 11 ++- x/bep3/spec/05_params.md | 5 +- x/bep3/types/errors.go | 30 +++--- x/bep3/types/params.go | 50 +++++++--- x/bep3/types/params_test.go | 93 +++++++++++-------- 15 files changed, 204 insertions(+), 105 deletions(-) diff --git a/contrib/testnet-6000/genesis_examples/wip_genesis.json b/contrib/testnet-6000/genesis_examples/wip_genesis.json index a9a9fae7..528b582a 100644 --- a/contrib/testnet-6000/genesis_examples/wip_genesis.json +++ b/contrib/testnet-6000/genesis_examples/wip_genesis.json @@ -47,7 +47,8 @@ "assets_supplies": [], "atomic_swaps": [], "params": { - "bnb_deputy_address": "kava1xy7hrjy9r0algz9w3gzm8u6mrpq97kwta747gj", + "bnb_deputy_address": "kava1aphsdnz5hu2t5ty2au6znprug5kx3zpy6zwq29", + "bnb_deputy_fixed_fee": "1000", "max_block_lock": "600", "min_block_lock": "80", "supported_assets": [ diff --git a/x/bep3/genesis_test.go b/x/bep3/genesis_test.go index 7e2302b7..ea7f4693 100644 --- a/x/bep3/genesis_test.go +++ b/x/bep3/genesis_test.go @@ -67,6 +67,15 @@ func (suite *GenesisTestSuite) TestGenesisState() { }, expectPass: true, }, + { + name: "0 deputy fees", + genState: func() app.GenesisState { + gs := baseGenState(suite.addrs[0]) + gs.Params.BnbDeputyFixedFee = 0 + return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)} + }, + expectPass: true, + }, { name: "incoming supply doesn't match amount in incoming atomic swaps", genState: func() app.GenesisState { diff --git a/x/bep3/keeper/integration_test.go b/x/bep3/keeper/integration_test.go index 1d910f0c..c1a6b5b7 100644 --- a/x/bep3/keeper/integration_test.go +++ b/x/bep3/keeper/integration_test.go @@ -31,12 +31,13 @@ func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amo func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) } func ts(minOffset int) int64 { return tmtime.Now().Add(time.Duration(minOffset) * time.Minute).Unix() } -func NewBep3GenStateMulti(deputy sdk.AccAddress) app.GenesisState { +func NewBep3GenStateMulti(deputyAddress sdk.AccAddress) app.GenesisState { bep3Genesis := types.GenesisState{ Params: bep3.Params{ - BnbDeputyAddress: deputy, - MinBlockLock: types.DefaultMinBlockLock, // 80 - MaxBlockLock: types.DefaultMaxBlockLock, // 360 + BnbDeputyAddress: deputyAddress, + BnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, // 1000 + MinBlockLock: types.DefaultMinBlockLock, // 80 + MaxBlockLock: types.DefaultMaxBlockLock, // 360 SupportedAssets: types.AssetParams{ types.AssetParam{ Denom: "bnb", diff --git a/x/bep3/keeper/params.go b/x/bep3/keeper/params.go index 825be35f..db342d6e 100644 --- a/x/bep3/keeper/params.go +++ b/x/bep3/keeper/params.go @@ -24,6 +24,12 @@ func (k Keeper) GetBnbDeputyAddress(ctx sdk.Context) sdk.AccAddress { return params.BnbDeputyAddress } +// GetBnbDeputyFixedFee returns the deputy's fixed fee +func (k Keeper) GetBnbDeputyFixedFee(ctx sdk.Context) uint64 { + params := k.GetParams(ctx) + return params.BnbDeputyFixedFee +} + // GetMaxBlockLock returns the maximum block lock func (k Keeper) GetMaxBlockLock(ctx sdk.Context) uint64 { params := k.GetParams(ctx) diff --git a/x/bep3/keeper/params_test.go b/x/bep3/keeper/params_test.go index 8c602dba..9ce33138 100644 --- a/x/bep3/keeper/params_test.go +++ b/x/bep3/keeper/params_test.go @@ -46,6 +46,14 @@ func (suite *ParamsTestSuite) TestGetSetBnbDeputyAddress() { suite.Equal(suite.addrs[1], addr) } +func (suite *ParamsTestSuite) TestGetBnbDeputyFixedFee() { + params := suite.keeper.GetParams(suite.ctx) + bnbDeputyFixedFee := params.BnbDeputyFixedFee + + res := suite.keeper.GetBnbDeputyFixedFee(suite.ctx) + suite.Equal(bnbDeputyFixedFee, res) +} + func (suite *ParamsTestSuite) TestGetMaxBlockLock() { params := suite.keeper.GetParams(suite.ctx) maxBlockLock := params.MaxBlockLock diff --git a/x/bep3/keeper/swap.go b/x/bep3/keeper/swap.go index 303c7302..725ec59d 100644 --- a/x/bep3/keeper/swap.go +++ b/x/bep3/keeper/swap.go @@ -62,13 +62,17 @@ func (k Keeper) CreateAtomicSwap(ctx sdk.Context, randomNumberHash []byte, times newAcc := k.accountKeeper.NewAccountWithAddress(ctx, recipient) k.accountKeeper.SetAccount(ctx, newAcc) } + // Incoming swaps have already had their fees collected by the deputy during the relay process. err = k.IncrementIncomingAssetSupply(ctx, amount[0]) case types.Outgoing: + // Amount in outgoing swaps must be greater than the deputy's fixed fee. + if amount[0].Amount.Uint64() <= k.GetBnbDeputyFixedFee(ctx) { + return sdkerrors.Wrap(types.ErrInsufficientAmount, amount[0].String()) + } err = k.IncrementOutgoingAssetSupply(ctx, amount[0]) default: err = fmt.Errorf("invalid swap direction: %s", direction.String()) } - if err != nil { return err } diff --git a/x/bep3/keeper/swap_test.go b/x/bep3/keeper/swap_test.go index adb36f25..96bb5a45 100644 --- a/x/bep3/keeper/swap_test.go +++ b/x/bep3/keeper/swap_test.go @@ -142,12 +142,31 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() { true, }, { - "unsupported asset", + + "outgoing swap amount not greater than fixed fee", currentTmTime, args{ randomNumberHash: suite.randomNumberHashes[1], timestamp: suite.timestamps[1], heightSpan: uint64(360), + sender: suite.addrs[1], + recipient: suite.addrs[2], + senderOtherChain: TestSenderOtherChain, + recipientOtherChain: TestRecipientOtherChain, + coins: cs(c(BNB_DENOM, int64(suite.keeper.GetBnbDeputyFixedFee(suite.ctx)))), + crossChain: true, + direction: types.Outgoing, + }, + false, + false, + }, + { + "unsupported asset", + currentTmTime, + args{ + randomNumberHash: suite.randomNumberHashes[2], + timestamp: suite.timestamps[2], + heightSpan: uint64(360), sender: suite.deputy, recipient: suite.addrs[2], senderOtherChain: TestSenderOtherChain, @@ -160,11 +179,11 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() { false, }, { - "past timestamp", + "outside timestamp range", currentTmTime, args{ - randomNumberHash: suite.randomNumberHashes[2], - timestamp: suite.timestamps[2] - 2000, + randomNumberHash: suite.randomNumberHashes[3], + timestamp: suite.timestamps[3] - 2000, heightSpan: uint64(360), sender: suite.deputy, recipient: suite.addrs[3], @@ -181,8 +200,8 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() { "future timestamp", currentTmTime, args{ - randomNumberHash: suite.randomNumberHashes[3], - timestamp: suite.timestamps[3] + 5000, + randomNumberHash: suite.randomNumberHashes[4], + timestamp: suite.timestamps[4] + 5000, heightSpan: uint64(360), sender: suite.deputy, recipient: suite.addrs[4], @@ -199,8 +218,8 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() { "small height span", currentTmTime, args{ - randomNumberHash: suite.randomNumberHashes[4], - timestamp: suite.timestamps[4], + randomNumberHash: suite.randomNumberHashes[5], + timestamp: suite.timestamps[5], heightSpan: uint64(5), sender: suite.deputy, recipient: suite.addrs[5], @@ -217,8 +236,8 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() { "big height span", currentTmTime, args{ - randomNumberHash: suite.randomNumberHashes[5], - timestamp: suite.timestamps[5], + randomNumberHash: suite.randomNumberHashes[6], + timestamp: suite.timestamps[6], heightSpan: uint64(1000000), sender: suite.deputy, recipient: suite.addrs[6], @@ -235,8 +254,8 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() { "zero amount", currentTmTime, args{ - randomNumberHash: suite.randomNumberHashes[6], - timestamp: suite.timestamps[6], + randomNumberHash: suite.randomNumberHashes[7], + timestamp: suite.timestamps[7], heightSpan: uint64(360), sender: suite.deputy, recipient: suite.addrs[7], diff --git a/x/bep3/simulation/genesis.go b/x/bep3/simulation/genesis.go index 12b529f1..f48287cf 100644 --- a/x/bep3/simulation/genesis.go +++ b/x/bep3/simulation/genesis.go @@ -36,6 +36,13 @@ func GenRandBnbDeputy(r *rand.Rand) simulation.Account { return acc } +// GenRandBnbDeputyFixedFee randomized BnbDeputyFixedFee in range [2, 10000] +func GenRandBnbDeputyFixedFee(r *rand.Rand) uint64 { + min := int(2) + max := int(10000) + return uint64(r.Intn(max-min) + min) +} + // GenMinBlockLock randomized MinBlockLock func GenMinBlockLock(r *rand.Rand) uint64 { min := int(types.AbsoluteMinimumBlockLock) @@ -100,6 +107,7 @@ func RandomizedGenState(simState *module.SimulationState) { func loadRandomBep3GenState(simState *module.SimulationState) types.GenesisState { bnbDeputy := GenRandBnbDeputy(simState.Rand) + bnbDeputyFixedFee := GenRandBnbDeputyFixedFee(simState.Rand) // min/max block lock are hardcoded to 50/100 for expected -NumBlocks=100 minBlockLock := types.AbsoluteMinimumBlockLock @@ -113,10 +121,11 @@ func loadRandomBep3GenState(simState *module.SimulationState) types.GenesisState bep3Genesis := types.GenesisState{ Params: types.Params{ - BnbDeputyAddress: bnbDeputy.Address, - MinBlockLock: minBlockLock, - MaxBlockLock: maxBlockLock, - SupportedAssets: supportedAssets, + BnbDeputyAddress: bnbDeputy.Address, + BnbDeputyFixedFee: bnbDeputyFixedFee, + MinBlockLock: minBlockLock, + MaxBlockLock: maxBlockLock, + SupportedAssets: supportedAssets, }, } diff --git a/x/bep3/simulation/operations.go b/x/bep3/simulation/operations.go index 2d521343..e91dfa30 100644 --- a/x/bep3/simulation/operations.go +++ b/x/bep3/simulation/operations.go @@ -65,10 +65,11 @@ func SimulateMsgCreateAtomicSwap(ak types.AccountKeeper, k keeper.Keeper) simula }) // Search for an account that holds coins received by an atomic swap + bnbDeputyFixedFee := k.GetBnbDeputyFixedFee(ctx) senderOut, asset, found := findValidAccountAssetSupplyPair(accs, supplies, func(acc simulation.Account, asset types.AssetSupply) bool { if asset.CurrentSupply.Amount.IsPositive() { authAcc := ak.GetAccount(ctx, acc.Address) - if authAcc.SpendableCoins(ctx.BlockTime()).AmountOf(asset.Denom).IsPositive() { + if authAcc.SpendableCoins(ctx.BlockTime()).AmountOf(asset.Denom).GT(sdk.NewIntFromUint64(bnbDeputyFixedFee)) { return true } } @@ -129,7 +130,7 @@ func SimulateMsgCreateAtomicSwap(ak types.AccountKeeper, k keeper.Keeper) simula // Get an amount of coins between 0.1 and 2% of total coins amount := maximumAmount.Quo(sdk.NewInt(int64(simulation.RandIntBetween(r, 50, 1000)))) - if amount.IsZero() { + if amount.LT(sdk.NewIntFromUint64(bnbDeputyFixedFee)) { return simulation.NewOperationMsgBasic(types.ModuleName, fmt.Sprintf("no-operation (all funds exhausted for asset %s)", denom), "", false, nil), nil, nil } coins := sdk.NewCoins(sdk.NewCoin(denom, amount)) diff --git a/x/bep3/simulation/params.go b/x/bep3/simulation/params.go index 76656750..d4764c09 100644 --- a/x/bep3/simulation/params.go +++ b/x/bep3/simulation/params.go @@ -10,10 +10,11 @@ import ( ) const ( - keyBnbDeputyAddress = "BnbDeputyAddress" - keyMinBlockLock = "MinBlockLock" - keyMaxBlockLock = "MaxBlockLock" - keySupportedAssets = "SupportedAssets" + keyBnbDeputyAddress = "BnbDeputyAddress" + keyBnbDeputyFixedFee = "BnbDeputyFixedFee" + keyMinBlockLock = "MinBlockLock" + keyMaxBlockLock = "MaxBlockLock" + keySupportedAssets = "SupportedAssets" ) // ParamChanges defines the parameters that can be modified by param change proposals @@ -27,6 +28,11 @@ func ParamChanges(r *rand.Rand) []simulation.ParamChange { return fmt.Sprintf("\"%s\"", GenRandBnbDeputy(r).Address) }, ), + simulation.NewSimParamChange(types.ModuleName, keyBnbDeputyFixedFee, + func(r *rand.Rand) string { + return fmt.Sprintf("\"%d\"", GenRandBnbDeputyFixedFee(r)) + }, + ), simulation.NewSimParamChange(types.ModuleName, keyMinBlockLock, func(r *rand.Rand) string { return fmt.Sprintf("\"%d\"", minBlockLockVal) diff --git a/x/bep3/spec/02_state.md b/x/bep3/spec/02_state.md index 45232c9c..50b6a958 100644 --- a/x/bep3/spec/02_state.md +++ b/x/bep3/spec/02_state.md @@ -7,10 +7,11 @@ ```go // Params governance parameters for bep3 module type Params struct { - BnbDeputyAddress sdk.AccAddress `json:"bnb_deputy_address" yaml:"bnb_deputy_address"` // deputy's address on Kava - MinBlockLock int64 `json:"min_block_lock" yaml:"min_block_lock"` // minimum swap expire height - MaxBlockLock int64 `json:"max_block_lock" yaml:"max_block_lock"` // maximum swap expire height - SupportedAssets AssetParams `json:"supported_assets" yaml:"supported_assets"` // array of supported asset + BnbDeputyAddress sdk.AccAddress `json:"bnb_deputy_address" yaml:"bnb_deputy_address"` // deputy's address on Kava + BnbDeputyFixedFee uint64 `json:"bnb_deputy_fixed_fee" yaml:"bnb_deputy_fixed_fee"` // deputy's fixed fee + MinBlockLock uint64 `json:"min_block_lock" yaml:"min_block_lock"` // minimum swap expire height + MaxBlockLock uint64 `json:"max_block_lock" yaml:"max_block_lock"` // maximum swap expire height + SupportedAssets AssetParams `json:"supported_assets" yaml:"supported_assets"` // array of supported asset } // AssetParam governance parameters for each asset within a supported chain @@ -76,6 +77,6 @@ type AssetSupply struct { IncomingSupply sdk.Coin `json:"incoming_supply" yaml:"incoming_supply"` OutgoingSupply sdk.Coin `json:"outgoing_supply" yaml:"outgoing_supply"` CurrentSupply sdk.Coin `json:"current_supply" yaml:"current_supply"` - Limit sdk.Coin `json:"limit" yaml:"limit"` + SupplyLimit sdk.Coin `json:"supply_limit" yaml:"supply_limit"` } ``` \ No newline at end of file diff --git a/x/bep3/spec/05_params.md b/x/bep3/spec/05_params.md index bcb0b51f..d51312dd 100644 --- a/x/bep3/spec/05_params.md +++ b/x/bep3/spec/05_params.md @@ -5,8 +5,9 @@ The bep3 module contains the following parameters: | Key | Type | Example | Description | |-------------------|-------------------------|-----------------------------------------------|-------------------------------| | BnbDeputyAddress | string (sdk.AccAddress) | "kava1xy7hrjy9r0algz9w3gzm8u6mrpq97kwta747gj" | deputy's Kava address | -| MinBlockLock | int64 | 80 | minimum swap expire height | -| MaxBlockLock | int64 | 600 | maximum swap expire height | +| BnbDeputyFixedFee | uint64 | 1000 | deputy's fixed bnb fee | +| MinBlockLock | uint64 | 80 | minimum swap expire height | +| MaxBlockLock | uint64 | 600 | maximum swap expire height | | SupportedAssets | AssetParams | []AssetParam | array of supported assets | |-------------------|-------------------------|-----------------------------------------------|-------------------------------| | AssetParam | AssetParam | AssetParam{"bnb", 714, sdk.NewInt(100), true} | a supported asset | diff --git a/x/bep3/types/errors.go b/x/bep3/types/errors.go index 71939c46..442c82ec 100644 --- a/x/bep3/types/errors.go +++ b/x/bep3/types/errors.go @@ -9,32 +9,34 @@ import ( var ( // ErrInvalidTimestamp error for when an timestamp is outside of bounds. Assumes block time of 10 seconds. ErrInvalidTimestamp = sdkerrors.Register(ModuleName, 2, "timestamp can neither be 15 minutes ahead of the current time, nor 30 minutes later") - // ErrInvalidHeightSpan error a proposed height span is outside of lock time range + // ErrInvalidHeightSpan error for when a proposed height span is outside of lock time range ErrInvalidHeightSpan = sdkerrors.Register(ModuleName, 3, "height span is outside acceptable range") + // ErrInsufficientAmount error for when a swap's amount is less than the deputy fixed fee + ErrInsufficientAmount = sdkerrors.Register(ModuleName, 4, "amount must be greater than the deputy fixed fee") // ErrAssetNotSupported error for when an asset is not supported - ErrAssetNotSupported = sdkerrors.Register(ModuleName, 4, "asset not on the list of supported assets") + ErrAssetNotSupported = sdkerrors.Register(ModuleName, 5, "asset not on the list of supported assets") // ErrAssetNotActive error for when an asset is currently inactive - ErrAssetNotActive = sdkerrors.Register(ModuleName, 5, "asset is currently inactive") + ErrAssetNotActive = sdkerrors.Register(ModuleName, 6, "asset is currently inactive") // ErrAssetSupplyNotFound error for when an asset's supply is not found in the store - ErrAssetSupplyNotFound = sdkerrors.Register(ModuleName, 6, "asset supply not found in store") + ErrAssetSupplyNotFound = sdkerrors.Register(ModuleName, 7, "asset supply not found in store") // ErrExceedsSupplyLimit error for when the proposed supply increase would put the supply above limit - ErrExceedsSupplyLimit = sdkerrors.Register(ModuleName, 7, "asset supply over limit") + ErrExceedsSupplyLimit = sdkerrors.Register(ModuleName, 8, "asset supply over limit") // ErrExceedsAvailableSupply error for when the proposed outgoing amount exceeds the total available supply - ErrExceedsAvailableSupply = sdkerrors.Register(ModuleName, 8, "outgoing swap exceeds total available supply") + ErrExceedsAvailableSupply = sdkerrors.Register(ModuleName, 9, "outgoing swap exceeds total available supply") // ErrInvalidCurrentSupply error for when the proposed decrease would result in a negative current supplyx - ErrInvalidCurrentSupply = sdkerrors.Register(ModuleName, 9, "supply decrease puts current asset supply below 0") + ErrInvalidCurrentSupply = sdkerrors.Register(ModuleName, 10, "supply decrease puts current asset supply below 0") // ErrInvalidIncomingSupply error for when the proposed decrease would result in a negative incoming supply - ErrInvalidIncomingSupply = sdkerrors.Register(ModuleName, 10, "supply decrease puts incoming asset supply below 0") + ErrInvalidIncomingSupply = sdkerrors.Register(ModuleName, 11, "supply decrease puts incoming asset supply below 0") // ErrInvalidOutgoingSupply error for when the proposed decrease would result in a negative outgoing supply - ErrInvalidOutgoingSupply = sdkerrors.Register(ModuleName, 11, "supply decrease puts outgoing asset supply below 0") + ErrInvalidOutgoingSupply = sdkerrors.Register(ModuleName, 12, "supply decrease puts outgoing asset supply below 0") // ErrInvalidClaimSecret error when a submitted secret doesn't match an AtomicSwap's swapID - ErrInvalidClaimSecret = sdkerrors.Register(ModuleName, 12, "hashed claim attempt does not match") + ErrInvalidClaimSecret = sdkerrors.Register(ModuleName, 13, "hashed claim attempt does not match") // ErrAtomicSwapAlreadyExists error for when an AtomicSwap with this swapID already exists - ErrAtomicSwapAlreadyExists = sdkerrors.Register(ModuleName, 13, "atomic swap already exists") + ErrAtomicSwapAlreadyExists = sdkerrors.Register(ModuleName, 14, "atomic swap already exists") // ErrAtomicSwapNotFound error for when an atomic swap is not found - ErrAtomicSwapNotFound = sdkerrors.Register(ModuleName, 14, "atomic swap not found") + ErrAtomicSwapNotFound = sdkerrors.Register(ModuleName, 15, "atomic swap not found") // ErrSwapNotRefundable error for when an AtomicSwap has not expired and cannot be refunded - ErrSwapNotRefundable = sdkerrors.Register(ModuleName, 15, "atomic swap is still active and cannot be refunded") + ErrSwapNotRefundable = sdkerrors.Register(ModuleName, 16, "atomic swap is still active and cannot be refunded") // ErrSwapNotClaimable error for when an atomic swap is not open and cannot be claimed - ErrSwapNotClaimable = sdkerrors.Register(ModuleName, 16, "atomic swap is not claimable") + ErrSwapNotClaimable = sdkerrors.Register(ModuleName, 17, "atomic swap is not claimable") ) diff --git a/x/bep3/types/params.go b/x/bep3/types/params.go index 73b23ab3..fef7e44f 100644 --- a/x/bep3/types/params.go +++ b/x/bep3/types/params.go @@ -15,11 +15,13 @@ const ( // Parameter keys var ( - KeyBnbDeputyAddress = []byte("BnbDeputyAddress") - KeyMinBlockLock = []byte("MinBlockLock") - KeyMaxBlockLock = []byte("MaxBlockLock") - KeySupportedAssets = []byte("SupportedAssets") + KeyBnbDeputyAddress = []byte("BnbDeputyAddress") + KeyBnbDeputyFixedFee = []byte("BnbDeputyFixedFee") + KeyMinBlockLock = []byte("MinBlockLock") + KeyMaxBlockLock = []byte("MaxBlockLock") + KeySupportedAssets = []byte("SupportedAssets") + DefaultBnbDeputyFixedFee uint64 = 1000 AbsoluteMaximumBlockLock uint64 = 10000 AbsoluteMinimumBlockLock uint64 = 50 DefaultMinBlockLock uint64 = 80 @@ -36,30 +38,33 @@ var ( // Params governance parameters for bep3 module type Params struct { - BnbDeputyAddress sdk.AccAddress `json:"bnb_deputy_address" yaml:"bnb_deputy_address"` // Bnbchain deputy address - MinBlockLock uint64 `json:"min_block_lock" yaml:"min_block_lock"` // AtomicSwap minimum block lock - MaxBlockLock uint64 `json:"max_block_lock" yaml:"max_block_lock"` // AtomicSwap maximum block lock - SupportedAssets AssetParams `json:"supported_assets" yaml:"supported_assets"` // Supported assets + BnbDeputyAddress sdk.AccAddress `json:"bnb_deputy_address" yaml:"bnb_deputy_address"` // Bnbchain deputy address + BnbDeputyFixedFee uint64 `json:"bnb_deputy_fixed_fee" yaml:"bnb_deputy_fixed_fee"` // Deputy fixed fee in BNB + MinBlockLock uint64 `json:"min_block_lock" yaml:"min_block_lock"` // AtomicSwap minimum block lock + MaxBlockLock uint64 `json:"max_block_lock" yaml:"max_block_lock"` // AtomicSwap maximum block lock + SupportedAssets AssetParams `json:"supported_assets" yaml:"supported_assets"` // Supported assets } // String implements fmt.Stringer func (p Params) String() string { return fmt.Sprintf(`Params: Bnbchain deputy address: %s, + Deputy fixed fee (BNB): %d, Min block lock: %d, Max block lock: %d, Supported assets: %s`, - p.BnbDeputyAddress.String(), p.MinBlockLock, p.MaxBlockLock, p.SupportedAssets) + p.BnbDeputyAddress.String(), p.BnbDeputyFixedFee, p.MinBlockLock, p.MaxBlockLock, p.SupportedAssets) } // NewParams returns a new params object -func NewParams(bnbDeputyAddress sdk.AccAddress, minBlockLock, maxBlockLock uint64, supportedAssets AssetParams, +func NewParams(bnbDeputyAddress sdk.AccAddress, bnbDeputyFixedFee, minBlockLock, maxBlockLock uint64, supportedAssets AssetParams, ) Params { return Params{ - BnbDeputyAddress: bnbDeputyAddress, - MinBlockLock: minBlockLock, - MaxBlockLock: maxBlockLock, - SupportedAssets: supportedAssets, + BnbDeputyAddress: bnbDeputyAddress, + BnbDeputyFixedFee: bnbDeputyFixedFee, + MinBlockLock: minBlockLock, + MaxBlockLock: maxBlockLock, + SupportedAssets: supportedAssets, } } @@ -70,7 +75,8 @@ func DefaultParams() Params { panic(err) } - return NewParams(defaultBnbDeputyAddress, DefaultMinBlockLock, DefaultMaxBlockLock, DefaultSupportedAssets) + return NewParams(defaultBnbDeputyAddress, DefaultBnbDeputyFixedFee, + DefaultMinBlockLock, DefaultMaxBlockLock, DefaultSupportedAssets) } // AssetParam governance parameters for each asset within a supported chain @@ -114,6 +120,7 @@ func ParamKeyTable() params.KeyTable { func (p *Params) ParamSetPairs() params.ParamSetPairs { return params.ParamSetPairs{ params.NewParamSetPair(KeyBnbDeputyAddress, &p.BnbDeputyAddress, validateBnbDeputyAddressParam), + params.NewParamSetPair(KeyBnbDeputyFixedFee, &p.BnbDeputyFixedFee, validateBnbDeputyFixedFeeParam), params.NewParamSetPair(KeyMinBlockLock, &p.MinBlockLock, validateMinBlockLockParam), params.NewParamSetPair(KeyMaxBlockLock, &p.MaxBlockLock, validateMaxBlockLockParam), params.NewParamSetPair(KeySupportedAssets, &p.SupportedAssets, validateSupportedAssetsParams), @@ -126,6 +133,10 @@ func (p Params) Validate() error { return err } + if err := validateBnbDeputyFixedFeeParam(p.BnbDeputyFixedFee); err != nil { + return err + } + if err := validateMinBlockLockParam(p.MinBlockLock); err != nil { return err } @@ -158,6 +169,15 @@ func validateBnbDeputyAddressParam(i interface{}) error { return nil } +func validateBnbDeputyFixedFeeParam(i interface{}) error { + _, ok := i.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + return nil +} + func validateMinBlockLockParam(i interface{}) error { minBlockLock, ok := i.(uint64) if !ok { diff --git a/x/bep3/types/params_test.go b/x/bep3/types/params_test.go index f8bc1536..ab730c86 100644 --- a/x/bep3/types/params_test.go +++ b/x/bep3/types/params_test.go @@ -28,10 +28,11 @@ func (suite *ParamsTestSuite) TestParamValidation() { type LoadParams func() types.Params type args struct { - bnbDeputyAddress sdk.AccAddress - minBlockLock uint64 - maxBlockLock uint64 - supportedAssets types.AssetParams + bnbDeputyAddress sdk.AccAddress + bnbDeputyFixedFee uint64 + minBlockLock uint64 + maxBlockLock uint64 + supportedAssets types.AssetParams } testCases := []struct { @@ -43,10 +44,11 @@ func (suite *ParamsTestSuite) TestParamValidation() { { name: "default", args: args{ - bnbDeputyAddress: suite.addr, - minBlockLock: types.DefaultMinBlockLock, - maxBlockLock: types.DefaultMaxBlockLock, - supportedAssets: types.DefaultSupportedAssets, + bnbDeputyAddress: suite.addr, + bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, + minBlockLock: types.DefaultMinBlockLock, + maxBlockLock: types.DefaultMaxBlockLock, + supportedAssets: types.DefaultSupportedAssets, }, expectPass: true, expectedErr: "", @@ -54,10 +56,11 @@ func (suite *ParamsTestSuite) TestParamValidation() { { name: "minimum block lock below limit", args: args{ - bnbDeputyAddress: suite.addr, - minBlockLock: 1, - maxBlockLock: types.DefaultMaxBlockLock, - supportedAssets: types.DefaultSupportedAssets, + bnbDeputyAddress: suite.addr, + bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, + minBlockLock: 1, + maxBlockLock: types.DefaultMaxBlockLock, + supportedAssets: types.DefaultSupportedAssets, }, expectPass: false, expectedErr: "minimum block lock cannot be less than", @@ -65,10 +68,11 @@ func (suite *ParamsTestSuite) TestParamValidation() { { name: "minimum block lock above limit", args: args{ - bnbDeputyAddress: suite.addr, - minBlockLock: 500000, - maxBlockLock: types.DefaultMaxBlockLock, - supportedAssets: types.DefaultSupportedAssets, + bnbDeputyAddress: suite.addr, + bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, + minBlockLock: 500000, + maxBlockLock: types.DefaultMaxBlockLock, + supportedAssets: types.DefaultSupportedAssets, }, expectPass: false, expectedErr: "maximum block lock must be greater than minimum block lock", @@ -76,10 +80,11 @@ func (suite *ParamsTestSuite) TestParamValidation() { { name: "maximum block lock below limit", args: args{ - bnbDeputyAddress: suite.addr, - minBlockLock: types.DefaultMinBlockLock, - maxBlockLock: 1, - supportedAssets: types.DefaultSupportedAssets, + bnbDeputyAddress: suite.addr, + bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, + minBlockLock: types.DefaultMinBlockLock, + maxBlockLock: 1, + supportedAssets: types.DefaultSupportedAssets, }, expectPass: false, expectedErr: "maximum block lock must be greater than minimum block lock", @@ -87,10 +92,11 @@ func (suite *ParamsTestSuite) TestParamValidation() { { name: "maximum block lock above limit", args: args{ - bnbDeputyAddress: suite.addr, - minBlockLock: types.DefaultMinBlockLock, - maxBlockLock: 100000000, - supportedAssets: types.DefaultSupportedAssets, + bnbDeputyAddress: suite.addr, + bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, + minBlockLock: types.DefaultMinBlockLock, + maxBlockLock: 100000000, + supportedAssets: types.DefaultSupportedAssets, }, expectPass: false, expectedErr: "maximum block lock cannot be greater than", @@ -98,9 +104,10 @@ func (suite *ParamsTestSuite) TestParamValidation() { { name: "empty asset denom", args: args{ - bnbDeputyAddress: suite.addr, - minBlockLock: types.DefaultMinBlockLock, - maxBlockLock: types.DefaultMaxBlockLock, + bnbDeputyAddress: suite.addr, + bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, + minBlockLock: types.DefaultMinBlockLock, + maxBlockLock: types.DefaultMaxBlockLock, supportedAssets: types.AssetParams{ types.AssetParam{ Denom: "", @@ -116,9 +123,10 @@ func (suite *ParamsTestSuite) TestParamValidation() { { name: "negative asset coin ID", args: args{ - bnbDeputyAddress: suite.addr, - minBlockLock: types.DefaultMinBlockLock, - maxBlockLock: types.DefaultMaxBlockLock, + bnbDeputyAddress: suite.addr, + bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, + minBlockLock: types.DefaultMinBlockLock, + maxBlockLock: types.DefaultMaxBlockLock, supportedAssets: types.AssetParams{ types.AssetParam{ Denom: "bnb", @@ -134,9 +142,10 @@ func (suite *ParamsTestSuite) TestParamValidation() { { name: "negative asset limit", args: args{ - bnbDeputyAddress: suite.addr, - minBlockLock: types.DefaultMinBlockLock, - maxBlockLock: types.DefaultMaxBlockLock, + bnbDeputyAddress: suite.addr, + bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, + minBlockLock: types.DefaultMinBlockLock, + maxBlockLock: types.DefaultMaxBlockLock, supportedAssets: types.AssetParams{ types.AssetParam{ Denom: "bnb", @@ -152,9 +161,10 @@ func (suite *ParamsTestSuite) TestParamValidation() { { name: "duplicate asset denom", args: args{ - bnbDeputyAddress: suite.addr, - minBlockLock: types.DefaultMinBlockLock, - maxBlockLock: types.DefaultMaxBlockLock, + bnbDeputyAddress: suite.addr, + bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, + minBlockLock: types.DefaultMinBlockLock, + maxBlockLock: types.DefaultMaxBlockLock, supportedAssets: types.AssetParams{ types.AssetParam{ Denom: "bnb", @@ -176,9 +186,10 @@ func (suite *ParamsTestSuite) TestParamValidation() { { name: "duplicate asset coin ID", args: args{ - bnbDeputyAddress: suite.addr, - minBlockLock: types.DefaultMinBlockLock, - maxBlockLock: types.DefaultMaxBlockLock, + bnbDeputyAddress: suite.addr, + bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, + minBlockLock: types.DefaultMinBlockLock, + maxBlockLock: types.DefaultMaxBlockLock, supportedAssets: types.AssetParams{ types.AssetParam{ Denom: "bnb", @@ -200,8 +211,8 @@ func (suite *ParamsTestSuite) TestParamValidation() { } for _, tc := range testCases { - params := types.NewParams(tc.args.bnbDeputyAddress, tc.args.minBlockLock, - tc.args.maxBlockLock, tc.args.supportedAssets) + params := types.NewParams(tc.args.bnbDeputyAddress, tc.args.bnbDeputyFixedFee, + tc.args.minBlockLock, tc.args.maxBlockLock, tc.args.supportedAssets) err := params.Validate() if tc.expectPass {