[R4R] optional bep3 config params (#546)

* add minAmount, maxAmount

* update kava-3 params for compile

* fix migration script

* update to mainnet params

* remove height span validation for incoming swaps

* update to sdk.Int, set lock to 220

* update lock range to [220, 270]

* update bep3 module docs

* update MsgClaim's ValidateBasic

* update test comments
This commit is contained in:
Denali Marsh 2020-06-04 16:03:14 -07:00 committed by GitHub
parent c049aad495
commit 09a75bd7c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 336 additions and 191 deletions

View File

@ -49,14 +49,16 @@
"params": { "params": {
"bnb_deputy_address": "kava1tfvn5t8qwngqd2q427za2mel48pcus3z9u73fl", "bnb_deputy_address": "kava1tfvn5t8qwngqd2q427za2mel48pcus3z9u73fl",
"bnb_deputy_fixed_fee": "1000", "bnb_deputy_fixed_fee": "1000",
"max_block_lock": "600", "min_amount": "0",
"min_block_lock": "80", "max_amount": "1000000000000",
"min_block_lock": "220",
"max_block_lock": "270",
"supported_assets": [ "supported_assets": [
{ {
"active": true, "active": true,
"coin_id": "714", "coin_id": "714",
"denom": "bnb", "denom": "bnb",
"limit": "10000000000000" "limit": "350000000000000"
} }
] ]
} }

View File

@ -111,7 +111,9 @@ func addBep3State(cdc *codec.Codec, appState genutil.AppMap) {
appState[bep3.ModuleName] = cdc.MustMarshalJSON(bep3.NewGenesisState( appState[bep3.ModuleName] = cdc.MustMarshalJSON(bep3.NewGenesisState(
bep3.NewParams( bep3.NewParams(
mustAccAddressFromBech32(deputyAddressBech32), mustAccAddressFromBech32(deputyAddressBech32),
1000, bep3.DefaultBnbDeputyFixedFee,
bep3.DefaultMinAmount,
bep3.DefaultMaxAmount,
bep3.DefaultMinBlockLock, bep3.DefaultMinBlockLock,
bep3.DefaultMaxBlockLock, bep3.DefaultMaxBlockLock,
bep3.AssetParams{{ bep3.AssetParams{{

View File

@ -306,13 +306,15 @@
"params": { "params": {
"bnb_deputy_address": "kava1xy7hrjy9r0algz9w3gzm8u6mrpq97kwta747gj", "bnb_deputy_address": "kava1xy7hrjy9r0algz9w3gzm8u6mrpq97kwta747gj",
"bnb_deputy_fixed_fee": "1000", "bnb_deputy_fixed_fee": "1000",
"min_block_lock": "80", "min_amount": "0",
"max_block_lock": "600", "max_amount": "1000000000000",
"min_block_lock": "220",
"max_block_lock": "270",
"supported_assets": [ "supported_assets": [
{ {
"denom": "bnb", "denom": "bnb",
"coin_id": "714", "coin_id": "714",
"limit": "100000000000", "limit": "350000000000000",
"active": true "active": true
} }
] ]

View File

@ -52,8 +52,8 @@ func (suite *ABCITestSuite) ResetKeeper() {
var randomNumbers []tmbytes.HexBytes var randomNumbers []tmbytes.HexBytes
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
// Set up atomic swap variables // Set up atomic swap variables
expireHeight := uint64(360) expireHeight := bep3.DefaultMinBlockLock
amount := cs(c("bnb", int64(100))) amount := cs(c("bnb", int64(10000)))
timestamp := ts(i) timestamp := ts(i)
randomNumber, _ := bep3.GenerateSecureRandomNumber() randomNumber, _ := bep3.GenerateSecureRandomNumber()
randomNumberHash := bep3.CalculateRandomHash(randomNumber[:], timestamp) randomNumberHash := bep3.CalculateRandomHash(randomNumber[:], timestamp)

View File

@ -73,6 +73,7 @@ var (
ErrInvalidClaimSecret = types.ErrInvalidClaimSecret ErrInvalidClaimSecret = types.ErrInvalidClaimSecret
ErrInvalidCurrentSupply = types.ErrInvalidCurrentSupply ErrInvalidCurrentSupply = types.ErrInvalidCurrentSupply
ErrInvalidHeightSpan = types.ErrInvalidHeightSpan ErrInvalidHeightSpan = types.ErrInvalidHeightSpan
ErrInvalidAmount = types.ErrInvalidAmount
ErrInvalidIncomingSupply = types.ErrInvalidIncomingSupply ErrInvalidIncomingSupply = types.ErrInvalidIncomingSupply
ErrInvalidOutgoingSupply = types.ErrInvalidOutgoingSupply ErrInvalidOutgoingSupply = types.ErrInvalidOutgoingSupply
ErrInvalidTimestamp = types.ErrInvalidTimestamp ErrInvalidTimestamp = types.ErrInvalidTimestamp
@ -96,17 +97,21 @@ var (
RegisterCodec = types.RegisterCodec RegisterCodec = types.RegisterCodec
// variable aliases // variable aliases
AbsoluteMaximumBlockLock = types.AbsoluteMaximumBlockLock
AbsoluteMinimumBlockLock = types.AbsoluteMinimumBlockLock
AssetSupplyKeyPrefix = types.AssetSupplyKeyPrefix AssetSupplyKeyPrefix = types.AssetSupplyKeyPrefix
AtomicSwapByBlockPrefix = types.AtomicSwapByBlockPrefix AtomicSwapByBlockPrefix = types.AtomicSwapByBlockPrefix
AtomicSwapCoinsAccAddr = types.AtomicSwapCoinsAccAddr AtomicSwapCoinsAccAddr = types.AtomicSwapCoinsAccAddr
AtomicSwapKeyPrefix = types.AtomicSwapKeyPrefix AtomicSwapKeyPrefix = types.AtomicSwapKeyPrefix
AtomicSwapLongtermStoragePrefix = types.AtomicSwapLongtermStoragePrefix AtomicSwapLongtermStoragePrefix = types.AtomicSwapLongtermStoragePrefix
DefaultBnbDeputyFixedFee = types.DefaultBnbDeputyFixedFee
DefaultMinAmount = types.DefaultMinAmount
DefaultMaxAmount = types.DefaultMaxAmount
DefaultMaxBlockLock = types.DefaultMaxBlockLock DefaultMaxBlockLock = types.DefaultMaxBlockLock
DefaultMinBlockLock = types.DefaultMinBlockLock DefaultMinBlockLock = types.DefaultMinBlockLock
DefaultSupportedAssets = types.DefaultSupportedAssets DefaultSupportedAssets = types.DefaultSupportedAssets
KeyBnbDeputyAddress = types.KeyBnbDeputyAddress KeyBnbDeputyAddress = types.KeyBnbDeputyAddress
KeyBnbDeputyFixedFee = types.KeyBnbDeputyFixedFee
KeyMinAmount = types.KeyMinAmount
KeyMaxAmount = types.KeyMaxAmount
KeyMaxBlockLock = types.KeyMaxBlockLock KeyMaxBlockLock = types.KeyMaxBlockLock
KeyMinBlockLock = types.KeyMinBlockLock KeyMinBlockLock = types.KeyMinBlockLock
KeySupportedAssets = types.KeySupportedAssets KeySupportedAssets = types.KeySupportedAssets

View File

@ -71,7 +71,7 @@ func (suite *GenesisTestSuite) TestGenesisState() {
name: "0 deputy fees", name: "0 deputy fees",
genState: func() app.GenesisState { genState: func() app.GenesisState {
gs := baseGenState(suite.addrs[0]) gs := baseGenState(suite.addrs[0])
gs.Params.BnbDeputyFixedFee = 0 gs.Params.BnbDeputyFixedFee = sdk.ZeroInt()
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)} return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
}, },
expectPass: true, expectPass: true,
@ -119,7 +119,7 @@ func (suite *GenesisTestSuite) TestGenesisState() {
randomNumber, _ := bep3.GenerateSecureRandomNumber() randomNumber, _ := bep3.GenerateSecureRandomNumber()
randomNumberHash := bep3.CalculateRandomHash(randomNumber[:], timestamp) randomNumberHash := bep3.CalculateRandomHash(randomNumber[:], timestamp)
swap := bep3.NewAtomicSwap(cs(c("bnb", overLimitAmount.Int64())), randomNumberHash, swap := bep3.NewAtomicSwap(cs(c("bnb", overLimitAmount.Int64())), randomNumberHash,
uint64(360), timestamp, suite.addrs[0], addrs[1], TestSenderOtherChain, bep3.DefaultMinBlockLock, timestamp, suite.addrs[0], addrs[1], TestSenderOtherChain,
TestRecipientOtherChain, 0, bep3.Open, true, bep3.Incoming) TestRecipientOtherChain, 0, bep3.Open, true, bep3.Incoming)
gs.AtomicSwaps = bep3.AtomicSwaps{swap} gs.AtomicSwaps = bep3.AtomicSwaps{swap}
@ -222,37 +222,11 @@ func (suite *GenesisTestSuite) TestGenesisState() {
expectPass: false, expectPass: false,
}, },
{ {
name: "minimum block lock below limit", name: "minimum block lock cannot be > maximum block lock",
genState: func() app.GenesisState { genState: func() app.GenesisState {
gs := baseGenState(suite.addrs[0]) gs := baseGenState(suite.addrs[0])
gs.Params.MinBlockLock = 1 gs.Params.MinBlockLock = 201
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)} gs.Params.MaxBlockLock = 200
},
expectPass: false,
},
{
name: "minimum block lock above limit",
genState: func() app.GenesisState {
gs := baseGenState(suite.addrs[0])
gs.Params.MinBlockLock = 500000
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
},
expectPass: false,
},
{
name: "maximum block lock below limit",
genState: func() app.GenesisState {
gs := baseGenState(suite.addrs[0])
gs.Params.MaxBlockLock = 1
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
},
expectPass: false,
},
{
name: "maximum block lock above limit",
genState: func() app.GenesisState {
gs := baseGenState(suite.addrs[0])
gs.Params.MaxBlockLock = 100000000
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)} return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
}, },
expectPass: false, expectPass: false,

View File

@ -47,7 +47,7 @@ func (suite *HandlerTestSuite) SetupTest() {
} }
func (suite *HandlerTestSuite) AddAtomicSwap() (tmbytes.HexBytes, tmbytes.HexBytes) { func (suite *HandlerTestSuite) AddAtomicSwap() (tmbytes.HexBytes, tmbytes.HexBytes) {
expireHeight := uint64(360) expireHeight := bep3.DefaultMinBlockLock
amount := cs(c("bnb", int64(50000))) amount := cs(c("bnb", int64(50000)))
timestamp := ts(0) timestamp := ts(0)
randomNumber, _ := bep3.GenerateSecureRandomNumber() randomNumber, _ := bep3.GenerateSecureRandomNumber()
@ -72,7 +72,7 @@ func (suite *HandlerTestSuite) TestMsgCreateAtomicSwap() {
msg := bep3.NewMsgCreateAtomicSwap( msg := bep3.NewMsgCreateAtomicSwap(
suite.addrs[0], suite.addrs[2], TestRecipientOtherChain, suite.addrs[0], suite.addrs[2], TestRecipientOtherChain,
TestSenderOtherChain, randomNumberHash, timestamp, amount, TestSenderOtherChain, randomNumberHash, timestamp, amount,
uint64(300)) bep3.DefaultMinBlockLock)
res, err := suite.handler(suite.ctx, msg) res, err := suite.handler(suite.ctx, msg)
suite.Require().NoError(err) suite.Require().NoError(err)

View File

@ -37,9 +37,12 @@ func NewBep3GenStateMulti(deputy sdk.AccAddress) app.GenesisState {
func baseGenState(deputy sdk.AccAddress) bep3.GenesisState { func baseGenState(deputy sdk.AccAddress) bep3.GenesisState {
bep3Genesis := bep3.GenesisState{ bep3Genesis := bep3.GenesisState{
Params: bep3.Params{ Params: bep3.Params{
BnbDeputyAddress: deputy, BnbDeputyAddress: deputy,
MinBlockLock: bep3.DefaultMinBlockLock, // 80 BnbDeputyFixedFee: bep3.DefaultBnbDeputyFixedFee, // 1,000
MaxBlockLock: bep3.DefaultMaxBlockLock, // 360 MinAmount: bep3.DefaultMinAmount, // 0
MaxAmount: bep3.DefaultMaxAmount, // 10,000
MinBlockLock: bep3.DefaultMinBlockLock, // 220
MaxBlockLock: bep3.DefaultMaxBlockLock, // 270
SupportedAssets: bep3.AssetParams{ SupportedAssets: bep3.AssetParams{
bep3.AssetParam{ bep3.AssetParam{
Denom: "btc", Denom: "btc",
@ -73,8 +76,8 @@ func baseGenState(deputy sdk.AccAddress) bep3.GenesisState {
func loadSwapAndSupply(addr sdk.AccAddress, index int) (bep3.AtomicSwap, bep3.AssetSupply) { func loadSwapAndSupply(addr sdk.AccAddress, index int) (bep3.AtomicSwap, bep3.AssetSupply) {
coin := c(DenomMap[index], 50000) coin := c(DenomMap[index], 50000)
expireOffset := uint64((index * 15) + 360) // Default expire height + offet to match timestamp expireOffset := bep3.DefaultMinBlockLock // Default expire height + offet to match timestamp
timestamp := ts(index) // One minute apart timestamp := ts(index) // One minute apart
randomNumber, _ := bep3.GenerateSecureRandomNumber() randomNumber, _ := bep3.GenerateSecureRandomNumber()
randomNumberHash := bep3.CalculateRandomHash(randomNumber[:], timestamp) randomNumberHash := bep3.CalculateRandomHash(randomNumber[:], timestamp)
swap := bep3.NewAtomicSwap(cs(coin), randomNumberHash, swap := bep3.NewAtomicSwap(cs(coin), randomNumberHash,

View File

@ -20,7 +20,7 @@ const (
) )
var ( var (
StandardSupplyLimit = i(100000000000) StandardSupplyLimit = i(350000000000000)
DenomMap = map[int]string{0: "btc", 1: "eth", 2: "bnb", 3: "xrp", 4: "dai"} DenomMap = map[int]string{0: "btc", 1: "eth", 2: "bnb", 3: "xrp", 4: "dai"}
TestUser1 = sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser1"))) TestUser1 = sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser1")))
TestUser2 = sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser2"))) TestUser2 = sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser2")))
@ -36,8 +36,10 @@ func NewBep3GenStateMulti(deputyAddress sdk.AccAddress) app.GenesisState {
Params: bep3.Params{ Params: bep3.Params{
BnbDeputyAddress: deputyAddress, BnbDeputyAddress: deputyAddress,
BnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, // 1000 BnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, // 1000
MinBlockLock: types.DefaultMinBlockLock, // 80 MinAmount: types.DefaultMinAmount, // 0
MaxBlockLock: types.DefaultMaxBlockLock, // 360 MaxAmount: types.DefaultMaxAmount, // 10,000
MinBlockLock: types.DefaultMinBlockLock, // 220
MaxBlockLock: types.DefaultMaxBlockLock, // 270
SupportedAssets: types.AssetParams{ SupportedAssets: types.AssetParams{
types.AssetParam{ types.AssetParam{
Denom: "bnb", Denom: "bnb",
@ -67,8 +69,8 @@ func atomicSwaps(ctx sdk.Context, count int) types.AtomicSwaps {
} }
func atomicSwap(ctx sdk.Context, index int) types.AtomicSwap { func atomicSwap(ctx sdk.Context, index int) types.AtomicSwap {
expireOffset := uint64((index * 15) + 360) // Default expire height + offet to match timestamp expireOffset := uint64(200) // Default expire height + offet to match timestamp
timestamp := ts(index) // One minute apart timestamp := ts(index) // One minute apart
randomNumber, _ := types.GenerateSecureRandomNumber() randomNumber, _ := types.GenerateSecureRandomNumber()
randomNumberHash := types.CalculateRandomHash(randomNumber[:], timestamp) randomNumberHash := types.CalculateRandomHash(randomNumber[:], timestamp)

View File

@ -25,15 +25,21 @@ func (k Keeper) GetBnbDeputyAddress(ctx sdk.Context) sdk.AccAddress {
} }
// GetBnbDeputyFixedFee returns the deputy's fixed fee // GetBnbDeputyFixedFee returns the deputy's fixed fee
func (k Keeper) GetBnbDeputyFixedFee(ctx sdk.Context) uint64 { func (k Keeper) GetBnbDeputyFixedFee(ctx sdk.Context) sdk.Int {
params := k.GetParams(ctx) params := k.GetParams(ctx)
return params.BnbDeputyFixedFee return params.BnbDeputyFixedFee
} }
// GetMaxBlockLock returns the maximum block lock // GetMinAmount returns the minimum amount
func (k Keeper) GetMaxBlockLock(ctx sdk.Context) uint64 { func (k Keeper) GetMinAmount(ctx sdk.Context) sdk.Int {
params := k.GetParams(ctx) params := k.GetParams(ctx)
return params.MaxBlockLock return params.MinAmount
}
// GetMaxAmount returns the maximum amount
func (k Keeper) GetMaxAmount(ctx sdk.Context) sdk.Int {
params := k.GetParams(ctx)
return params.MaxAmount
} }
// GetMinBlockLock returns the minimum block lock // GetMinBlockLock returns the minimum block lock
@ -42,6 +48,12 @@ func (k Keeper) GetMinBlockLock(ctx sdk.Context) uint64 {
return params.MinBlockLock return params.MinBlockLock
} }
// GetMaxBlockLock returns the maximum block lock
func (k Keeper) GetMaxBlockLock(ctx sdk.Context) uint64 {
params := k.GetParams(ctx)
return params.MaxBlockLock
}
// GetAssets returns a list containing all supported assets // GetAssets returns a list containing all supported assets
func (k Keeper) GetAssets(ctx sdk.Context) (types.AssetParams, bool) { func (k Keeper) GetAssets(ctx sdk.Context) (types.AssetParams, bool) {
params := k.GetParams(ctx) params := k.GetParams(ctx)

View File

@ -54,12 +54,20 @@ func (suite *ParamsTestSuite) TestGetBnbDeputyFixedFee() {
suite.Equal(bnbDeputyFixedFee, res) suite.Equal(bnbDeputyFixedFee, res)
} }
func (suite *ParamsTestSuite) TestGetMaxBlockLock() { func (suite *ParamsTestSuite) TestGetMinAmount() {
params := suite.keeper.GetParams(suite.ctx) params := suite.keeper.GetParams(suite.ctx)
maxBlockLock := params.MaxBlockLock minAmount := params.MinAmount
res := suite.keeper.GetMaxBlockLock(suite.ctx) res := suite.keeper.GetMinAmount(suite.ctx)
suite.Equal(maxBlockLock, res) suite.Equal(minAmount, res)
}
func (suite *ParamsTestSuite) TestGetMaxAmount() {
params := suite.keeper.GetParams(suite.ctx)
maxAmount := params.MaxAmount
res := suite.keeper.GetMaxAmount(suite.ctx)
suite.Equal(maxAmount, res)
} }
func (suite *ParamsTestSuite) TestGetMinBlockLock() { func (suite *ParamsTestSuite) TestGetMinBlockLock() {
@ -70,6 +78,14 @@ func (suite *ParamsTestSuite) TestGetMinBlockLock() {
suite.Equal(minBlockLock, res) suite.Equal(minBlockLock, res)
} }
func (suite *ParamsTestSuite) TestGetMaxBlockLock() {
params := suite.keeper.GetParams(suite.ctx)
maxBlockLock := params.MaxBlockLock
res := suite.keeper.GetMaxBlockLock(suite.ctx)
suite.Equal(maxBlockLock, res)
}
func (suite *ParamsTestSuite) TestGetAssets() { func (suite *ParamsTestSuite) TestGetAssets() {
params := suite.keeper.GetParams(suite.ctx) params := suite.keeper.GetParams(suite.ctx)
assets := params.SupportedAssets assets := params.SupportedAssets

View File

@ -62,7 +62,7 @@ func (suite *QuerierTestSuite) SetupTest() {
isSwapID := make(map[string]bool) isSwapID := make(map[string]bool)
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
// Set up atomic swap variables // Set up atomic swap variables
expireHeight := uint64(360) expireHeight := types.DefaultMinBlockLock
amount := cs(c("bnb", 100)) amount := cs(c("bnb", 100))
timestamp := ts(0) timestamp := ts(0)
randomNumber, _ := types.GenerateSecureRandomNumber() randomNumber, _ := types.GenerateSecureRandomNumber()

View File

@ -28,19 +28,6 @@ func (k Keeper) CreateAtomicSwap(ctx sdk.Context, randomNumberHash []byte, times
return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is a module account", recipient) return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is a module account", recipient)
} }
// The heightSpan period should be more than 10 minutes and less than one week
// Assume average block time interval is 10 second. 10 mins = 60 blocks, 1 week = 60480 blocks
if heightSpan < k.GetMinBlockLock(ctx) || heightSpan > k.GetMaxBlockLock(ctx) {
return sdkerrors.Wrapf(types.ErrInvalidHeightSpan, "height span %d, range %d - %d", heightSpan, k.GetMinBlockLock(ctx), k.GetMaxBlockLock(ctx))
}
// Unix timestamp must be in range [-15 mins, 30 mins] of the current time
pastTimestampLimit := ctx.BlockTime().Add(time.Duration(-15) * time.Minute).Unix()
futureTimestampLimit := ctx.BlockTime().Add(time.Duration(30) * time.Minute).Unix()
if timestamp < pastTimestampLimit || timestamp >= futureTimestampLimit {
return sdkerrors.Wrap(types.ErrInvalidTimestamp, time.Unix(timestamp, 0).UTC().String())
}
if len(amount) != 1 { if len(amount) != 1 {
return fmt.Errorf("amount must contain exactly one coin") return fmt.Errorf("amount must contain exactly one coin")
} }
@ -50,6 +37,18 @@ func (k Keeper) CreateAtomicSwap(ctx sdk.Context, randomNumberHash []byte, times
return err return err
} }
// Swap amount must be within the specified swap amount limits
if amount[0].Amount.LT(k.GetMinAmount(ctx)) || amount[0].Amount.GT(k.GetMaxAmount(ctx)) {
return sdkerrors.Wrapf(types.ErrInvalidAmount, "amount %d outside range [%d, %d]", amount[0].Amount, k.GetMinAmount(ctx), k.GetMaxAmount(ctx))
}
// Unix timestamp must be in range [-15 mins, 30 mins] of the current time
pastTimestampLimit := ctx.BlockTime().Add(time.Duration(-15) * time.Minute).Unix()
futureTimestampLimit := ctx.BlockTime().Add(time.Duration(30) * time.Minute).Unix()
if timestamp < pastTimestampLimit || timestamp >= futureTimestampLimit {
return sdkerrors.Wrap(types.ErrInvalidTimestamp, time.Unix(timestamp, 0).UTC().String())
}
var direction types.SwapDirection var direction types.SwapDirection
deputy := k.GetBnbDeputyAddress(ctx) deputy := k.GetBnbDeputyAddress(ctx)
if sender.Equals(deputy) { if sender.Equals(deputy) {
@ -70,8 +69,12 @@ func (k Keeper) CreateAtomicSwap(ctx sdk.Context, randomNumberHash []byte, times
// Incoming swaps have already had their fees collected by the deputy during the relay process. // Incoming swaps have already had their fees collected by the deputy during the relay process.
err = k.IncrementIncomingAssetSupply(ctx, amount[0]) err = k.IncrementIncomingAssetSupply(ctx, amount[0])
case types.Outgoing: case types.Outgoing:
// Amount in outgoing swaps must be greater than the deputy's fixed fee. // Outoing swaps must have a height span within the accepted range
if amount[0].Amount.Uint64() <= k.GetBnbDeputyFixedFee(ctx) { if heightSpan < k.GetMinBlockLock(ctx) || heightSpan > k.GetMaxBlockLock(ctx) {
return sdkerrors.Wrapf(types.ErrInvalidHeightSpan, "height span %d outside range [%d, %d]", heightSpan, k.GetMinBlockLock(ctx), k.GetMaxBlockLock(ctx))
}
// Amount in outgoing swaps must be able to pay the deputy's fixed fee.
if amount[0].Amount.LTE(k.GetBnbDeputyFixedFee(ctx).Add(k.GetMinAmount(ctx))) {
return sdkerrors.Wrap(types.ErrInsufficientAmount, amount[0].String()) return sdkerrors.Wrap(types.ErrInsufficientAmount, amount[0].String())
} }
err = k.IncrementOutgoingAssetSupply(ctx, amount[0]) err = k.IncrementOutgoingAssetSupply(ctx, amount[0])

View File

@ -34,7 +34,7 @@ type AtomicSwapTestSuite struct {
} }
const ( const (
STARING_BNB_BALANCE = int64(1000000000) STARING_BNB_BALANCE = int64(3000000000000)
BNB_DENOM = "bnb" BNB_DENOM = "bnb"
) )
@ -84,7 +84,7 @@ func (suite *AtomicSwapTestSuite) GenerateSwapDetails() {
var timestamps []int64 var timestamps []int64
var randomNumberHashes []tmbytes.HexBytes var randomNumberHashes []tmbytes.HexBytes
var randomNumbers []tmbytes.HexBytes var randomNumbers []tmbytes.HexBytes
for i := 0; i < 10; i++ { for i := 0; i < 15; i++ {
// Set up atomic swap details // Set up atomic swap details
timestamp := ts(i) timestamp := ts(i)
randomNumber, _ := types.GenerateSecureRandomNumber() randomNumber, _ := types.GenerateSecureRandomNumber()
@ -126,7 +126,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
args{ args{
randomNumberHash: suite.randomNumberHashes[0], randomNumberHash: suite.randomNumberHashes[0],
timestamp: suite.timestamps[0], timestamp: suite.timestamps[0],
heightSpan: uint64(360), heightSpan: types.DefaultMinBlockLock,
sender: suite.deputy, sender: suite.deputy,
recipient: suite.addrs[1], recipient: suite.addrs[1],
senderOtherChain: TestSenderOtherChain, senderOtherChain: TestSenderOtherChain,
@ -144,7 +144,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
args{ args{
randomNumberHash: suite.randomNumberHashes[0], randomNumberHash: suite.randomNumberHashes[0],
timestamp: suite.timestamps[0], timestamp: suite.timestamps[0],
heightSpan: uint64(360), heightSpan: types.DefaultMinBlockLock,
sender: suite.addrs[1], sender: suite.addrs[1],
recipient: suite.addrs[2], recipient: suite.addrs[2],
senderOtherChain: TestSenderOtherChain, senderOtherChain: TestSenderOtherChain,
@ -163,12 +163,12 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
args{ args{
randomNumberHash: suite.randomNumberHashes[1], randomNumberHash: suite.randomNumberHashes[1],
timestamp: suite.timestamps[1], timestamp: suite.timestamps[1],
heightSpan: uint64(360), heightSpan: types.DefaultMinBlockLock,
sender: suite.addrs[1], sender: suite.addrs[1],
recipient: suite.addrs[2], recipient: suite.addrs[2],
senderOtherChain: TestSenderOtherChain, senderOtherChain: TestSenderOtherChain,
recipientOtherChain: TestRecipientOtherChain, recipientOtherChain: TestRecipientOtherChain,
coins: cs(c(BNB_DENOM, int64(suite.keeper.GetBnbDeputyFixedFee(suite.ctx)))), coins: cs(c(BNB_DENOM, suite.keeper.GetBnbDeputyFixedFee(suite.ctx).Int64())),
crossChain: true, crossChain: true,
direction: types.Outgoing, direction: types.Outgoing,
}, },
@ -181,7 +181,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
args{ args{
randomNumberHash: suite.randomNumberHashes[2], randomNumberHash: suite.randomNumberHashes[2],
timestamp: suite.timestamps[2], timestamp: suite.timestamps[2],
heightSpan: uint64(360), heightSpan: types.DefaultMinBlockLock,
sender: suite.deputy, sender: suite.deputy,
recipient: suite.addrs[2], recipient: suite.addrs[2],
senderOtherChain: TestSenderOtherChain, senderOtherChain: TestSenderOtherChain,
@ -199,7 +199,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
args{ args{
randomNumberHash: suite.randomNumberHashes[3], randomNumberHash: suite.randomNumberHashes[3],
timestamp: suite.timestamps[3] - 2000, timestamp: suite.timestamps[3] - 2000,
heightSpan: uint64(360), heightSpan: types.DefaultMinBlockLock,
sender: suite.deputy, sender: suite.deputy,
recipient: suite.addrs[3], recipient: suite.addrs[3],
senderOtherChain: TestSenderOtherChain, senderOtherChain: TestSenderOtherChain,
@ -217,7 +217,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
args{ args{
randomNumberHash: suite.randomNumberHashes[4], randomNumberHash: suite.randomNumberHashes[4],
timestamp: suite.timestamps[4] + 5000, timestamp: suite.timestamps[4] + 5000,
heightSpan: uint64(360), heightSpan: types.DefaultMinBlockLock,
sender: suite.deputy, sender: suite.deputy,
recipient: suite.addrs[4], recipient: suite.addrs[4],
senderOtherChain: TestSenderOtherChain, senderOtherChain: TestSenderOtherChain,
@ -230,37 +230,37 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
false, false,
}, },
{ {
"small height span", "small height span on outgoing swap",
currentTmTime, currentTmTime,
args{ args{
randomNumberHash: suite.randomNumberHashes[5], randomNumberHash: suite.randomNumberHashes[5],
timestamp: suite.timestamps[5], timestamp: suite.timestamps[5],
heightSpan: uint64(5), heightSpan: uint64(100),
sender: suite.deputy, sender: suite.addrs[5],
recipient: suite.addrs[5], recipient: suite.deputy,
senderOtherChain: TestSenderOtherChain, senderOtherChain: TestSenderOtherChain,
recipientOtherChain: TestRecipientOtherChain, recipientOtherChain: TestRecipientOtherChain,
coins: cs(c(BNB_DENOM, 50000)), coins: cs(c(BNB_DENOM, 50000)),
crossChain: true, crossChain: true,
direction: types.Incoming, direction: types.Outgoing,
}, },
false, false,
false, false,
}, },
{ {
"big height span", "big height span on outgoing swap",
currentTmTime, currentTmTime,
args{ args{
randomNumberHash: suite.randomNumberHashes[6], randomNumberHash: suite.randomNumberHashes[6],
timestamp: suite.timestamps[6], timestamp: suite.timestamps[6],
heightSpan: uint64(1000000), heightSpan: uint64(300),
sender: suite.deputy, sender: suite.addrs[6],
recipient: suite.addrs[6], recipient: suite.deputy,
senderOtherChain: TestSenderOtherChain, senderOtherChain: TestSenderOtherChain,
recipientOtherChain: TestRecipientOtherChain, recipientOtherChain: TestRecipientOtherChain,
coins: cs(c(BNB_DENOM, 50000)), coins: cs(c(BNB_DENOM, 50000)),
crossChain: true, crossChain: true,
direction: types.Incoming, direction: types.Outgoing,
}, },
false, false,
false, false,
@ -271,7 +271,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
args{ args{
randomNumberHash: suite.randomNumberHashes[7], randomNumberHash: suite.randomNumberHashes[7],
timestamp: suite.timestamps[7], timestamp: suite.timestamps[7],
heightSpan: uint64(360), heightSpan: types.DefaultMinBlockLock,
sender: suite.deputy, sender: suite.deputy,
recipient: suite.addrs[7], recipient: suite.addrs[7],
senderOtherChain: TestSenderOtherChain, senderOtherChain: TestSenderOtherChain,
@ -289,7 +289,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
args{ args{
randomNumberHash: suite.randomNumberHashes[0], randomNumberHash: suite.randomNumberHashes[0],
timestamp: suite.timestamps[0], timestamp: suite.timestamps[0],
heightSpan: uint64(360), heightSpan: types.DefaultMinBlockLock,
sender: suite.deputy, sender: suite.deputy,
recipient: suite.addrs[1], recipient: suite.addrs[1],
senderOtherChain: TestSenderOtherChain, senderOtherChain: TestSenderOtherChain,
@ -307,7 +307,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
args{ args{
randomNumberHash: suite.randomNumberHashes[8], randomNumberHash: suite.randomNumberHashes[8],
timestamp: suite.timestamps[8], timestamp: suite.timestamps[8],
heightSpan: uint64(360), heightSpan: types.DefaultMinBlockLock,
sender: suite.deputy, sender: suite.deputy,
recipient: suite.randMacc, recipient: suite.randMacc,
senderOtherChain: TestSenderOtherChain, senderOtherChain: TestSenderOtherChain,
@ -319,6 +319,42 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
false, false,
false, false,
}, },
{
"exactly at maximum amount",
currentTmTime,
args{
randomNumberHash: suite.randomNumberHashes[10],
timestamp: suite.timestamps[10],
heightSpan: types.DefaultMinBlockLock,
sender: suite.deputy,
recipient: suite.addrs[4],
senderOtherChain: TestSenderOtherChain,
recipientOtherChain: TestRecipientOtherChain,
coins: cs(c(BNB_DENOM, 1000000000000)), // 10,000 BNB
crossChain: true,
direction: types.Incoming,
},
true,
true,
},
{
"above maximum amount",
currentTmTime,
args{
randomNumberHash: suite.randomNumberHashes[11],
timestamp: suite.timestamps[11],
heightSpan: types.DefaultMinBlockLock,
sender: suite.deputy,
recipient: suite.addrs[5],
senderOtherChain: TestSenderOtherChain,
recipientOtherChain: TestRecipientOtherChain,
coins: cs(c(BNB_DENOM, 1000000000001)), // 10,001 BNB
crossChain: true,
direction: types.Incoming,
},
false,
false,
},
} }
for _, tc := range testCases { for _, tc := range testCases {
@ -503,7 +539,7 @@ func (suite *AtomicSwapTestSuite) TestClaimAtomicSwap() {
// Create atomic swap // Create atomic swap
err := suite.keeper.CreateAtomicSwap(suite.ctx, suite.randomNumberHashes[i], suite.timestamps[i], err := suite.keeper.CreateAtomicSwap(suite.ctx, suite.randomNumberHashes[i], suite.timestamps[i],
uint64(360), sender, expectedRecipient, TestSenderOtherChain, TestRecipientOtherChain, types.DefaultMinBlockLock, sender, expectedRecipient, TestSenderOtherChain, TestRecipientOtherChain,
expectedClaimAmount, true) expectedClaimAmount, true)
suite.NoError(err) suite.NoError(err)
@ -657,7 +693,7 @@ func (suite *AtomicSwapTestSuite) TestRefundAtomicSwap() {
} }
err := suite.keeper.CreateAtomicSwap(suite.ctx, suite.randomNumberHashes[i], suite.timestamps[i], err := suite.keeper.CreateAtomicSwap(suite.ctx, suite.randomNumberHashes[i], suite.timestamps[i],
uint64(360), sender, suite.addrs[9], TestSenderOtherChain, TestRecipientOtherChain, types.DefaultMinBlockLock, sender, suite.addrs[9], TestSenderOtherChain, TestRecipientOtherChain,
expectedRefundAmount, true) expectedRefundAmount, true)
suite.NoError(err) suite.NoError(err)

View File

@ -18,10 +18,13 @@ import (
// Simulation parameter constants // Simulation parameter constants
const ( const (
BnbDeputyAddress = "bnb_deputy_address" BnbDeputyAddress = "bnb_deputy_address"
MinBlockLock = "min_block_lock" BnbDeputyFixedFee = "bnb_deputy_fixed_fee"
MaxBlockLock = "max_block_lock" MinAmount = "min_amount"
SupportedAssets = "supported_assets" MaxAmount = "max_amount"
MinBlockLock = "min_block_lock"
MaxBlockLock = "max_block_lock"
SupportedAssets = "supported_assets"
) )
var ( var (
@ -37,23 +40,37 @@ func GenRandBnbDeputy(r *rand.Rand) simulation.Account {
} }
// GenRandBnbDeputyFixedFee randomized BnbDeputyFixedFee in range [2, 10000] // GenRandBnbDeputyFixedFee randomized BnbDeputyFixedFee in range [2, 10000]
func GenRandBnbDeputyFixedFee(r *rand.Rand) uint64 { func GenRandBnbDeputyFixedFee(r *rand.Rand) sdk.Int {
min := int(2) min := int(2)
max := int(10000) max := types.DefaultBnbDeputyFixedFee.Int64()
return uint64(r.Intn(max-min) + min) return sdk.NewInt(int64(r.Intn(int(max)-min) + min))
}
// GenMinAmount randomized MinAmount in range [0, 1000000000000]
func GenMinAmount(r *rand.Rand) sdk.Int {
min := types.DefaultMinAmount.Int64()
max := types.DefaultMaxAmount.Int64()
return sdk.NewInt((int64(r.Intn(int(max-min))) + min))
}
// GenMaxAmount randomized MaxAmount
func GenMaxAmount(r *rand.Rand, minAmount sdk.Int) sdk.Int {
min := minAmount.Int64()
max := types.DefaultMaxAmount.Int64()
return sdk.NewInt((int64(r.Intn(int(max-min))) + min))
} }
// GenMinBlockLock randomized MinBlockLock // GenMinBlockLock randomized MinBlockLock
func GenMinBlockLock(r *rand.Rand) uint64 { func GenMinBlockLock(r *rand.Rand) uint64 {
min := int(types.AbsoluteMinimumBlockLock) min := 20
max := int(types.AbsoluteMaximumBlockLock) max := int(types.DefaultMaxBlockLock)
return uint64(r.Intn(max-min) + min) return uint64(r.Intn(max-min) + min)
} }
// GenMaxBlockLock randomized MaxBlockLock // GenMaxBlockLock randomized MaxBlockLock
func GenMaxBlockLock(r *rand.Rand, minBlockLock uint64) uint64 { func GenMaxBlockLock(r *rand.Rand, minBlockLock uint64) uint64 {
min := int(minBlockLock) min := int(minBlockLock)
max := int(types.AbsoluteMaximumBlockLock) max := int(types.DefaultMaxBlockLock)
return uint64(r.Intn(max-min) + min) return uint64(r.Intn(max-min) + min)
} }
@ -108,9 +125,11 @@ func RandomizedGenState(simState *module.SimulationState) {
func loadRandomBep3GenState(simState *module.SimulationState) types.GenesisState { func loadRandomBep3GenState(simState *module.SimulationState) types.GenesisState {
bnbDeputy := GenRandBnbDeputy(simState.Rand) bnbDeputy := GenRandBnbDeputy(simState.Rand)
bnbDeputyFixedFee := GenRandBnbDeputyFixedFee(simState.Rand) bnbDeputyFixedFee := GenRandBnbDeputyFixedFee(simState.Rand)
minAmount := types.DefaultMinAmount
maxAmount := GenMaxAmount(simState.Rand, minAmount)
// min/max block lock are hardcoded to 50/100 for expected -NumBlocks=100 // min/max block lock are hardcoded to 50/100 for expected -NumBlocks=100
minBlockLock := types.AbsoluteMinimumBlockLock minBlockLock := uint64(50)
maxBlockLock := minBlockLock * 2 maxBlockLock := minBlockLock * 2
var supportedAssets types.AssetParams var supportedAssets types.AssetParams
@ -123,6 +142,8 @@ func loadRandomBep3GenState(simState *module.SimulationState) types.GenesisState
Params: types.Params{ Params: types.Params{
BnbDeputyAddress: bnbDeputy.Address, BnbDeputyAddress: bnbDeputy.Address,
BnbDeputyFixedFee: bnbDeputyFixedFee, BnbDeputyFixedFee: bnbDeputyFixedFee,
MinAmount: minAmount,
MaxAmount: maxAmount,
MinBlockLock: minBlockLock, MinBlockLock: minBlockLock,
MaxBlockLock: maxBlockLock, MaxBlockLock: maxBlockLock,
SupportedAssets: supportedAssets, SupportedAssets: supportedAssets,

View File

@ -65,11 +65,11 @@ func SimulateMsgCreateAtomicSwap(ak types.AccountKeeper, k keeper.Keeper) simula
}) })
// Search for an account that holds coins received by an atomic swap // Search for an account that holds coins received by an atomic swap
bnbDeputyFixedFee := k.GetBnbDeputyFixedFee(ctx) minAmountPlusFee := k.GetMinAmount(ctx).Add(k.GetBnbDeputyFixedFee(ctx))
senderOut, asset, found := findValidAccountAssetSupplyPair(accs, supplies, func(acc simulation.Account, asset types.AssetSupply) bool { senderOut, asset, found := findValidAccountAssetSupplyPair(accs, supplies, func(acc simulation.Account, asset types.AssetSupply) bool {
if asset.CurrentSupply.Amount.IsPositive() { if asset.CurrentSupply.Amount.IsPositive() {
authAcc := ak.GetAccount(ctx, acc.Address) authAcc := ak.GetAccount(ctx, acc.Address)
if authAcc.SpendableCoins(ctx.BlockTime()).AmountOf(asset.Denom).GT(sdk.NewIntFromUint64(bnbDeputyFixedFee)) { if authAcc.SpendableCoins(ctx.BlockTime()).AmountOf(asset.Denom).GT(minAmountPlusFee) {
return true return true
} }
} }
@ -128,9 +128,14 @@ func SimulateMsgCreateAtomicSwap(ak types.AccountKeeper, k keeper.Keeper) simula
} }
} }
// The maximum amount for all swaps is limited by the total max limit
if maximumAmount.GT(k.GetMaxAmount(ctx)) {
maximumAmount = k.GetMaxAmount(ctx)
}
// Get an amount of coins between 0.1 and 2% of total coins // Get an amount of coins between 0.1 and 2% of total coins
amount := maximumAmount.Quo(sdk.NewInt(int64(simulation.RandIntBetween(r, 50, 1000)))) amount := maximumAmount.Quo(sdk.NewInt(int64(simulation.RandIntBetween(r, 50, 1000))))
if amount.LT(sdk.NewIntFromUint64(bnbDeputyFixedFee)) { if amount.LT(minAmountPlusFee) {
return simulation.NewOperationMsgBasic(types.ModuleName, fmt.Sprintf("no-operation (all funds exhausted for asset %s)", denom), "", false, nil), nil, nil 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)) coins := sdk.NewCoins(sdk.NewCoin(denom, amount))

View File

@ -12,6 +12,8 @@ import (
const ( const (
keyBnbDeputyAddress = "BnbDeputyAddress" keyBnbDeputyAddress = "BnbDeputyAddress"
keyBnbDeputyFixedFee = "BnbDeputyFixedFee" keyBnbDeputyFixedFee = "BnbDeputyFixedFee"
keyMinAmount = "MinAmount"
keyMaxAmount = "MaxAmount"
keyMinBlockLock = "MinBlockLock" keyMinBlockLock = "MinBlockLock"
keyMaxBlockLock = "MaxBlockLock" keyMaxBlockLock = "MaxBlockLock"
keySupportedAssets = "SupportedAssets" keySupportedAssets = "SupportedAssets"
@ -21,6 +23,7 @@ const (
func ParamChanges(r *rand.Rand) []simulation.ParamChange { func ParamChanges(r *rand.Rand) []simulation.ParamChange {
// We generate MinBlockLock first because the result is required by GenMaxBlockLock() // We generate MinBlockLock first because the result is required by GenMaxBlockLock()
minBlockLockVal := GenMinBlockLock(r) minBlockLockVal := GenMinBlockLock(r)
minAmount := GenMinAmount(r)
return []simulation.ParamChange{ return []simulation.ParamChange{
simulation.NewSimParamChange(types.ModuleName, keyBnbDeputyAddress, simulation.NewSimParamChange(types.ModuleName, keyBnbDeputyAddress,
@ -30,7 +33,17 @@ func ParamChanges(r *rand.Rand) []simulation.ParamChange {
), ),
simulation.NewSimParamChange(types.ModuleName, keyBnbDeputyFixedFee, simulation.NewSimParamChange(types.ModuleName, keyBnbDeputyFixedFee,
func(r *rand.Rand) string { func(r *rand.Rand) string {
return fmt.Sprintf("\"%d\"", GenRandBnbDeputyFixedFee(r)) return fmt.Sprintf("\"%s\"", GenRandBnbDeputyFixedFee(r).String())
},
),
simulation.NewSimParamChange(types.ModuleName, keyMinAmount,
func(r *rand.Rand) string {
return fmt.Sprintf("\"%s\"", minAmount.String())
},
),
simulation.NewSimParamChange(types.ModuleName, keyMaxAmount,
func(r *rand.Rand) string {
return fmt.Sprintf("\"%s\"", GenMaxAmount(r, minAmount).String())
}, },
), ),
simulation.NewSimParamChange(types.ModuleName, keyMinBlockLock, simulation.NewSimParamChange(types.ModuleName, keyMinBlockLock,

View File

@ -11,11 +11,13 @@ order: 2
```go ```go
// Params governance parameters for bep3 module // Params governance parameters for bep3 module
type Params struct { type Params struct {
BnbDeputyAddress sdk.AccAddress `json:"bnb_deputy_address" yaml:"bnb_deputy_address"` // deputy's address on Kava 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's fixed fee BnbDeputyFixedFee sdk.Int `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"` // minimum swap expire height MinAmount sdk.Int `json:"min_amount" yaml:"min_amount"` // Minimum swap amount
MaxBlockLock uint64 `json:"max_block_lock" yaml:"max_block_lock"` // maximum swap expire height MaxAmount sdk.Int `json:"max_amount" yaml:"max_amount"` // Maximum swap amount
SupportedAssets AssetParams `json:"supported_assets" yaml:"supported_assets"` // array of supported asset MinBlockLock uint64 `json:"min_block_lock" yaml:"min_block_lock"` // Minimum swap block lock
MaxBlockLock uint64 `json:"max_block_lock" yaml:"max_block_lock"` // Maximum swap block lock
SupportedAssets AssetParams `json:"supported_assets" yaml:"supported_assets"` // Supported assets
} }
// AssetParam governance parameters for each asset within a supported chain // AssetParam governance parameters for each asset within a supported chain

View File

@ -9,9 +9,11 @@ The bep3 module contains the following parameters:
| Key | Type | Example | Description | | Key | Type | Example | Description |
|-------------------|-------------------------|-----------------------------------------------|-------------------------------| |-------------------|-------------------------|-----------------------------------------------|-------------------------------|
| BnbDeputyAddress | string (sdk.AccAddress) | "kava1xy7hrjy9r0algz9w3gzm8u6mrpq97kwta747gj" | deputy's Kava address | | BnbDeputyAddress | string (sdk.AccAddress) | "kava1xy7hrjy9r0algz9w3gzm8u6mrpq97kwta747gj" | deputy's Kava address |
| BnbDeputyFixedFee | uint64 | 1000 | deputy's fixed bnb fee | | BnbDeputyFixedFee | sdk.Int | sdk.NewInt(1000) | deputy's fixed bnb fee |
| MinBlockLock | uint64 | 80 | minimum swap expire height | | MinAmount | sdk.Int | sdk.NewInt(0) | minimum swap amount |
| MaxBlockLock | uint64 | 600 | maximum swap expire height | | MaxAmount | sdk.Int | sdk.NewInt(1000000000000) | maximum swap amount |
| MinBlockLock | uint64 | 220 | minimum swap expire height |
| MaxBlockLock | uint64 | 270 | maximum swap expire height |
| SupportedAssets | AssetParams | []AssetParam | array of supported assets | | SupportedAssets | AssetParams | []AssetParam | array of supported assets |
|-------------------|-------------------------|-----------------------------------------------|-------------------------------| |-------------------|-------------------------|-----------------------------------------------|-------------------------------|
| AssetParam | AssetParam | AssetParam{"bnb", 714, sdk.NewInt(100), true} | a supported asset | | AssetParam | AssetParam | AssetParam{"bnb", 714, sdk.NewInt(100), true} | a supported asset |

View File

@ -11,8 +11,8 @@ var (
ErrInvalidTimestamp = sdkerrors.Register(ModuleName, 2, "timestamp can neither be 15 minutes ahead of the current time, nor 30 minutes later") ErrInvalidTimestamp = sdkerrors.Register(ModuleName, 2, "timestamp can neither be 15 minutes ahead of the current time, nor 30 minutes later")
// ErrInvalidHeightSpan error for when 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") 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 error for when a swap's amount cannot cover the deputy's fixed fee
ErrInsufficientAmount = sdkerrors.Register(ModuleName, 4, "amount must be greater than the deputy fixed fee") ErrInsufficientAmount = sdkerrors.Register(ModuleName, 4, "amount cannot cover the deputy fixed fee")
// ErrAssetNotSupported error for when an asset is not supported // ErrAssetNotSupported error for when an asset is not supported
ErrAssetNotSupported = sdkerrors.Register(ModuleName, 5, "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 error for when an asset is currently inactive
@ -39,4 +39,6 @@ var (
ErrSwapNotRefundable = sdkerrors.Register(ModuleName, 16, "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 error for when an atomic swap is not open and cannot be claimed
ErrSwapNotClaimable = sdkerrors.Register(ModuleName, 17, "atomic swap is not claimable") ErrSwapNotClaimable = sdkerrors.Register(ModuleName, 17, "atomic swap is not claimable")
// ErrInvalidAmount error for when a swap's amount is outside acceptable range
ErrInvalidAmount = sdkerrors.Register(ModuleName, 18, "amount is outside acceptable range")
) )

View File

@ -183,8 +183,8 @@ func (msg MsgClaimAtomicSwap) ValidateBasic() error {
if len(msg.SwapID) != SwapIDLength { if len(msg.SwapID) != SwapIDLength {
return fmt.Errorf("the length of swapID should be %d", SwapIDLength) return fmt.Errorf("the length of swapID should be %d", SwapIDLength)
} }
if len(msg.RandomNumber) == 0 { if len(msg.RandomNumber) != RandomNumberLength {
return errors.New("the length of random number cannot be 0") return fmt.Errorf("the length of random number should be %d", RandomNumberLength)
} }
return nil return nil
} }

View File

@ -17,20 +17,22 @@ const (
var ( var (
KeyBnbDeputyAddress = []byte("BnbDeputyAddress") KeyBnbDeputyAddress = []byte("BnbDeputyAddress")
KeyBnbDeputyFixedFee = []byte("BnbDeputyFixedFee") KeyBnbDeputyFixedFee = []byte("BnbDeputyFixedFee")
KeyMinAmount = []byte("MinAmount")
KeyMaxAmount = []byte("MaxAmount")
KeyMinBlockLock = []byte("MinBlockLock") KeyMinBlockLock = []byte("MinBlockLock")
KeyMaxBlockLock = []byte("MaxBlockLock") KeyMaxBlockLock = []byte("MaxBlockLock")
KeySupportedAssets = []byte("SupportedAssets") KeySupportedAssets = []byte("SupportedAssets")
DefaultBnbDeputyFixedFee uint64 = 1000 DefaultBnbDeputyFixedFee sdk.Int = sdk.NewInt(1000) // 0.00001 BNB
AbsoluteMaximumBlockLock uint64 = 10000 DefaultMinAmount sdk.Int = sdk.ZeroInt()
AbsoluteMinimumBlockLock uint64 = 50 DefaultMaxAmount sdk.Int = sdk.NewInt(1000000000000) // 10,000 BNB
DefaultMinBlockLock uint64 = 80 DefaultMinBlockLock uint64 = 220
DefaultMaxBlockLock uint64 = 600 DefaultMaxBlockLock uint64 = 270
DefaultSupportedAssets = AssetParams{ DefaultSupportedAssets = AssetParams{
AssetParam{ AssetParam{
Denom: "bnb", Denom: "bnb",
CoinID: 714, CoinID: 714,
Limit: sdk.NewInt(100000000000), Limit: sdk.NewInt(350000000000000), // 3,500,000 BNB
Active: true, Active: true,
}, },
} }
@ -39,9 +41,11 @@ var (
// Params governance parameters for bep3 module // Params governance parameters for bep3 module
type Params struct { type Params struct {
BnbDeputyAddress sdk.AccAddress `json:"bnb_deputy_address" yaml:"bnb_deputy_address"` // Bnbchain deputy address 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 BnbDeputyFixedFee sdk.Int `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 MinAmount sdk.Int `json:"min_amount" yaml:"min_amount"` // Minimum swap amount
MaxBlockLock uint64 `json:"max_block_lock" yaml:"max_block_lock"` // AtomicSwap maximum block lock MaxAmount sdk.Int `json:"max_amount" yaml:"max_amount"` // Maximum swap amount
MinBlockLock uint64 `json:"min_block_lock" yaml:"min_block_lock"` // Minimum swap block lock
MaxBlockLock uint64 `json:"max_block_lock" yaml:"max_block_lock"` // Maximum swap block lock
SupportedAssets AssetParams `json:"supported_assets" yaml:"supported_assets"` // Supported assets SupportedAssets AssetParams `json:"supported_assets" yaml:"supported_assets"` // Supported assets
} }
@ -50,18 +54,24 @@ func (p Params) String() string {
return fmt.Sprintf(`Params: return fmt.Sprintf(`Params:
Bnbchain deputy address: %s, Bnbchain deputy address: %s,
Deputy fixed fee (BNB): %d, Deputy fixed fee (BNB): %d,
Min amount: %d,
Max amount: %d,
Min block lock: %d, Min block lock: %d,
Max block lock: %d, Max block lock: %d,
Supported assets: %s`, Supported assets: %s`,
p.BnbDeputyAddress.String(), p.BnbDeputyFixedFee, p.MinBlockLock, p.MaxBlockLock, p.SupportedAssets) p.BnbDeputyAddress.String(), p.BnbDeputyFixedFee, p.MinAmount,
p.MaxAmount, p.MinBlockLock, p.MaxBlockLock, p.SupportedAssets)
} }
// NewParams returns a new params object // NewParams returns a new params object
func NewParams(bnbDeputyAddress sdk.AccAddress, bnbDeputyFixedFee, minBlockLock, maxBlockLock uint64, supportedAssets AssetParams, func NewParams(bnbDeputyAddress sdk.AccAddress, bnbDeputyFixedFee, minAmount,
maxAmount sdk.Int, minBlockLock, maxBlockLock uint64, supportedAssets AssetParams,
) Params { ) Params {
return Params{ return Params{
BnbDeputyAddress: bnbDeputyAddress, BnbDeputyAddress: bnbDeputyAddress,
BnbDeputyFixedFee: bnbDeputyFixedFee, BnbDeputyFixedFee: bnbDeputyFixedFee,
MinAmount: minAmount,
MaxAmount: maxAmount,
MinBlockLock: minBlockLock, MinBlockLock: minBlockLock,
MaxBlockLock: maxBlockLock, MaxBlockLock: maxBlockLock,
SupportedAssets: supportedAssets, SupportedAssets: supportedAssets,
@ -75,8 +85,8 @@ func DefaultParams() Params {
panic(err) panic(err)
} }
return NewParams(defaultBnbDeputyAddress, DefaultBnbDeputyFixedFee, return NewParams(defaultBnbDeputyAddress, DefaultBnbDeputyFixedFee, DefaultMinAmount,
DefaultMinBlockLock, DefaultMaxBlockLock, DefaultSupportedAssets) DefaultMaxAmount, DefaultMinBlockLock, DefaultMaxBlockLock, DefaultSupportedAssets)
} }
// AssetParam governance parameters for each asset within a supported chain // AssetParam governance parameters for each asset within a supported chain
@ -121,6 +131,8 @@ func (p *Params) ParamSetPairs() params.ParamSetPairs {
return params.ParamSetPairs{ return params.ParamSetPairs{
params.NewParamSetPair(KeyBnbDeputyAddress, &p.BnbDeputyAddress, validateBnbDeputyAddressParam), params.NewParamSetPair(KeyBnbDeputyAddress, &p.BnbDeputyAddress, validateBnbDeputyAddressParam),
params.NewParamSetPair(KeyBnbDeputyFixedFee, &p.BnbDeputyFixedFee, validateBnbDeputyFixedFeeParam), params.NewParamSetPair(KeyBnbDeputyFixedFee, &p.BnbDeputyFixedFee, validateBnbDeputyFixedFeeParam),
params.NewParamSetPair(KeyMinAmount, &p.MinAmount, validateMinAmountParam),
params.NewParamSetPair(KeyMaxAmount, &p.MaxAmount, validateMaxAmountParam),
params.NewParamSetPair(KeyMinBlockLock, &p.MinBlockLock, validateMinBlockLockParam), params.NewParamSetPair(KeyMinBlockLock, &p.MinBlockLock, validateMinBlockLockParam),
params.NewParamSetPair(KeyMaxBlockLock, &p.MaxBlockLock, validateMaxBlockLockParam), params.NewParamSetPair(KeyMaxBlockLock, &p.MaxBlockLock, validateMaxBlockLockParam),
params.NewParamSetPair(KeySupportedAssets, &p.SupportedAssets, validateSupportedAssetsParams), params.NewParamSetPair(KeySupportedAssets, &p.SupportedAssets, validateSupportedAssetsParams),
@ -137,6 +149,18 @@ func (p Params) Validate() error {
return err return err
} }
if err := validateMinAmountParam(p.MinAmount); err != nil {
return err
}
if err := validateMaxAmountParam(p.MaxAmount); err != nil {
return err
}
if p.MinAmount.GT(p.MaxAmount) {
return fmt.Errorf("minimum amount cannot be > maximum amount, got %d > %d", p.MinAmount, p.MaxAmount)
}
if err := validateMinBlockLockParam(p.MinBlockLock); err != nil { if err := validateMinBlockLockParam(p.MinBlockLock); err != nil {
return err return err
} }
@ -145,8 +169,8 @@ func (p Params) Validate() error {
return err return err
} }
if p.MinBlockLock >= p.MaxBlockLock { if p.MinBlockLock > p.MaxBlockLock {
return fmt.Errorf("minimum block lock cannot be ≥ maximum block lock, got %d ≥ %d", p.MinBlockLock, p.MaxBlockLock) return fmt.Errorf("minimum block lock cannot be > maximum block lock, got %d > %d", p.MinBlockLock, p.MaxBlockLock)
} }
return validateSupportedAssetsParams(p.SupportedAssets) return validateSupportedAssetsParams(p.SupportedAssets)
@ -170,7 +194,25 @@ func validateBnbDeputyAddressParam(i interface{}) error {
} }
func validateBnbDeputyFixedFeeParam(i interface{}) error { func validateBnbDeputyFixedFeeParam(i interface{}) error {
_, ok := i.(uint64) _, ok := i.(sdk.Int)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
return nil
}
func validateMinAmountParam(i interface{}) error {
_, ok := i.(sdk.Int)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
return nil
}
func validateMaxAmountParam(i interface{}) error {
_, ok := i.(sdk.Int)
if !ok { if !ok {
return fmt.Errorf("invalid parameter type: %T", i) return fmt.Errorf("invalid parameter type: %T", i)
} }
@ -179,28 +221,20 @@ func validateBnbDeputyFixedFeeParam(i interface{}) error {
} }
func validateMinBlockLockParam(i interface{}) error { func validateMinBlockLockParam(i interface{}) error {
minBlockLock, ok := i.(uint64) _, ok := i.(uint64)
if !ok { if !ok {
return fmt.Errorf("invalid parameter type: %T", i) return fmt.Errorf("invalid parameter type: %T", i)
} }
if minBlockLock < AbsoluteMinimumBlockLock {
return fmt.Errorf("minimum block lock cannot be less than %d, got %d", AbsoluteMinimumBlockLock, minBlockLock)
}
return nil return nil
} }
func validateMaxBlockLockParam(i interface{}) error { func validateMaxBlockLockParam(i interface{}) error {
maxBlockLock, ok := i.(uint64) _, ok := i.(uint64)
if !ok { if !ok {
return fmt.Errorf("invalid parameter type: %T", i) return fmt.Errorf("invalid parameter type: %T", i)
} }
if maxBlockLock > AbsoluteMaximumBlockLock {
return fmt.Errorf("maximum block lock cannot be greater than %d, got %d", AbsoluteMaximumBlockLock, maxBlockLock)
}
return nil return nil
} }

View File

@ -29,7 +29,9 @@ func (suite *ParamsTestSuite) TestParamValidation() {
type args struct { type args struct {
bnbDeputyAddress sdk.AccAddress bnbDeputyAddress sdk.AccAddress
bnbDeputyFixedFee uint64 bnbDeputyFixedFee sdk.Int
minAmount sdk.Int
maxAmount sdk.Int
minBlockLock uint64 minBlockLock uint64
maxBlockLock uint64 maxBlockLock uint64
supportedAssets types.AssetParams supportedAssets types.AssetParams
@ -46,6 +48,8 @@ func (suite *ParamsTestSuite) TestParamValidation() {
args: args{ args: args{
bnbDeputyAddress: suite.addr, bnbDeputyAddress: suite.addr,
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
minAmount: types.DefaultMinAmount,
maxAmount: types.DefaultMaxAmount,
minBlockLock: types.DefaultMinBlockLock, minBlockLock: types.DefaultMinBlockLock,
maxBlockLock: types.DefaultMaxBlockLock, maxBlockLock: types.DefaultMaxBlockLock,
supportedAssets: types.DefaultSupportedAssets, supportedAssets: types.DefaultSupportedAssets,
@ -54,58 +58,54 @@ func (suite *ParamsTestSuite) TestParamValidation() {
expectedErr: "", expectedErr: "",
}, },
{ {
name: "minimum block lock below limit", name: "minimum block lock == maximum block lock",
args: args{ args: args{
bnbDeputyAddress: suite.addr, bnbDeputyAddress: suite.addr,
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
minBlockLock: 1, minAmount: types.DefaultMinAmount,
maxAmount: types.DefaultMaxAmount,
minBlockLock: 243,
maxBlockLock: 243,
supportedAssets: types.DefaultSupportedAssets,
},
expectPass: true,
expectedErr: "",
},
{
name: "minimum amount greater than maximum amount",
args: args{
bnbDeputyAddress: suite.addr,
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
minAmount: sdk.NewInt(10000000),
maxAmount: sdk.NewInt(100000),
minBlockLock: types.DefaultMinBlockLock,
maxBlockLock: types.DefaultMaxBlockLock, maxBlockLock: types.DefaultMaxBlockLock,
supportedAssets: types.DefaultSupportedAssets, supportedAssets: types.DefaultSupportedAssets,
}, },
expectPass: false, expectPass: false,
expectedErr: "minimum block lock cannot be less than", expectedErr: "minimum amount cannot be > maximum amount",
}, },
{ {
name: "minimum block lock above limit", name: "minimum block lock greater than maximum block lock",
args: args{ args: args{
bnbDeputyAddress: suite.addr, bnbDeputyAddress: suite.addr,
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
minBlockLock: 500000, minAmount: types.DefaultMinAmount,
maxBlockLock: types.DefaultMaxBlockLock, maxAmount: types.DefaultMaxAmount,
minBlockLock: 500,
maxBlockLock: 400,
supportedAssets: types.DefaultSupportedAssets, supportedAssets: types.DefaultSupportedAssets,
}, },
expectPass: false, expectPass: false,
expectedErr: "maximum block lock must be greater than minimum block lock", expectedErr: "minimum block lock cannot be > maximum block lock",
},
{
name: "maximum block lock below limit",
args: args{
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",
},
{
name: "maximum block lock above limit",
args: args{
bnbDeputyAddress: suite.addr,
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
minBlockLock: types.DefaultMinBlockLock,
maxBlockLock: 100000000,
supportedAssets: types.DefaultSupportedAssets,
},
expectPass: false,
expectedErr: "maximum block lock cannot be greater than",
}, },
{ {
name: "empty asset denom", name: "empty asset denom",
args: args{ args: args{
bnbDeputyAddress: suite.addr, bnbDeputyAddress: suite.addr,
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
minAmount: types.DefaultMinAmount,
maxAmount: types.DefaultMaxAmount,
minBlockLock: types.DefaultMinBlockLock, minBlockLock: types.DefaultMinBlockLock,
maxBlockLock: types.DefaultMaxBlockLock, maxBlockLock: types.DefaultMaxBlockLock,
supportedAssets: types.AssetParams{ supportedAssets: types.AssetParams{
@ -125,6 +125,8 @@ func (suite *ParamsTestSuite) TestParamValidation() {
args: args{ args: args{
bnbDeputyAddress: suite.addr, bnbDeputyAddress: suite.addr,
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
minAmount: types.DefaultMinAmount,
maxAmount: types.DefaultMaxAmount,
minBlockLock: types.DefaultMinBlockLock, minBlockLock: types.DefaultMinBlockLock,
maxBlockLock: types.DefaultMaxBlockLock, maxBlockLock: types.DefaultMaxBlockLock,
supportedAssets: types.AssetParams{ supportedAssets: types.AssetParams{
@ -137,13 +139,15 @@ func (suite *ParamsTestSuite) TestParamValidation() {
}, },
}, },
expectPass: false, expectPass: false,
expectedErr: "must be a positive integer", expectedErr: "must be a non negative integer",
}, },
{ {
name: "negative asset limit", name: "negative asset limit",
args: args{ args: args{
bnbDeputyAddress: suite.addr, bnbDeputyAddress: suite.addr,
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
minAmount: types.DefaultMinAmount,
maxAmount: types.DefaultMaxAmount,
minBlockLock: types.DefaultMinBlockLock, minBlockLock: types.DefaultMinBlockLock,
maxBlockLock: types.DefaultMaxBlockLock, maxBlockLock: types.DefaultMaxBlockLock,
supportedAssets: types.AssetParams{ supportedAssets: types.AssetParams{
@ -163,6 +167,8 @@ func (suite *ParamsTestSuite) TestParamValidation() {
args: args{ args: args{
bnbDeputyAddress: suite.addr, bnbDeputyAddress: suite.addr,
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
minAmount: types.DefaultMinAmount,
maxAmount: types.DefaultMaxAmount,
minBlockLock: types.DefaultMinBlockLock, minBlockLock: types.DefaultMinBlockLock,
maxBlockLock: types.DefaultMaxBlockLock, maxBlockLock: types.DefaultMaxBlockLock,
supportedAssets: types.AssetParams{ supportedAssets: types.AssetParams{
@ -188,6 +194,8 @@ func (suite *ParamsTestSuite) TestParamValidation() {
args: args{ args: args{
bnbDeputyAddress: suite.addr, bnbDeputyAddress: suite.addr,
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
minAmount: types.DefaultMinAmount,
maxAmount: types.DefaultMaxAmount,
minBlockLock: types.DefaultMinBlockLock, minBlockLock: types.DefaultMinBlockLock,
maxBlockLock: types.DefaultMaxBlockLock, maxBlockLock: types.DefaultMaxBlockLock,
supportedAssets: types.AssetParams{ supportedAssets: types.AssetParams{
@ -211,14 +219,15 @@ func (suite *ParamsTestSuite) TestParamValidation() {
} }
for _, tc := range testCases { for _, tc := range testCases {
params := types.NewParams(tc.args.bnbDeputyAddress, tc.args.bnbDeputyFixedFee, params := types.NewParams(tc.args.bnbDeputyAddress, tc.args.bnbDeputyFixedFee, tc.args.minAmount,
tc.args.minBlockLock, tc.args.maxBlockLock, tc.args.supportedAssets) tc.args.maxAmount, tc.args.minBlockLock, tc.args.maxBlockLock, tc.args.supportedAssets)
err := params.Validate() err := params.Validate()
if tc.expectPass { if tc.expectPass {
suite.Require().NoError(err, tc.name) suite.Require().NoError(err, tc.name)
} else { } else {
suite.Require().Error(err, tc.name) suite.Require().Error(err, tc.name)
suite.Require().Contains(err.Error(), tc.expectedErr)
} }
} }
} }