mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-25 07:45:18 +00:00
BEP3: support multiple assets (#616)
* wip: refactor to allow multiple bep3 assets * update tests * sims: validate asset before claiming * move asset supply to params * update tests * fix sims * fix tests * wip: add migration from v0.9 -> v0.10 bep3 * fix build and migration tests * nit: rename file * move asset supply out of params * update committee tests * fix sims * address review comments * address review comments * address review comments
This commit is contained in:
parent
928ce5f064
commit
790753f156
@ -8,10 +8,10 @@ const (
|
||||
|
||||
// Default simulation operation weights for messages and gov proposals
|
||||
const (
|
||||
DefaultWeightMsgPlaceBid int = 75
|
||||
DefaultWeightMsgCreateAtomicSwap int = 50
|
||||
DefaultWeightMsgUpdatePrices int = 50
|
||||
DefaultWeightMsgCdp int = 100
|
||||
DefaultWeightMsgClaimReward int = 50
|
||||
OpWeightSubmitCommitteeChangeProposal int = 50
|
||||
DefaultWeightMsgPlaceBid int = 20
|
||||
DefaultWeightMsgCreateAtomicSwap int = 20
|
||||
DefaultWeightMsgUpdatePrices int = 20
|
||||
DefaultWeightMsgCdp int = 20
|
||||
DefaultWeightMsgClaimReward int = 20
|
||||
OpWeightSubmitCommitteeChangeProposal int = 20
|
||||
)
|
||||
|
@ -3,6 +3,7 @@ package app
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@ -110,6 +111,33 @@ func (tApp TestApp) InitializeFromGenesisStates(genesisStates ...GenesisState) T
|
||||
return tApp
|
||||
}
|
||||
|
||||
// InitializeFromGenesisStatesWithTime calls InitChain on the app using the default genesis state, overwitten with any passed in genesis states and genesis Time
|
||||
func (tApp TestApp) InitializeFromGenesisStatesWithTime(genTime time.Time, genesisStates ...GenesisState) TestApp {
|
||||
// Create a default genesis state and overwrite with provided values
|
||||
genesisState := NewDefaultGenesisState()
|
||||
for _, state := range genesisStates {
|
||||
for k, v := range state {
|
||||
genesisState[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the chain
|
||||
stateBytes, err := codec.MarshalJSONIndent(tApp.cdc, genesisState)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
tApp.InitChain(
|
||||
abci.RequestInitChain{
|
||||
Time: genTime,
|
||||
Validators: []abci.ValidatorUpdate{},
|
||||
AppStateBytes: stateBytes,
|
||||
},
|
||||
)
|
||||
tApp.Commit()
|
||||
tApp.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: tApp.LastBlockHeight() + 1}})
|
||||
return tApp
|
||||
}
|
||||
|
||||
func (tApp TestApp) CheckBalance(t *testing.T, ctx sdk.Context, owner sdk.AccAddress, expectedCoins sdk.Coins) {
|
||||
acc := tApp.GetAccountKeeper().GetAccount(ctx, owner)
|
||||
require.NotNilf(t, acc, "account with address '%s' doesn't exist", owner)
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
|
||||
"github.com/kava-labs/kava/x/auction"
|
||||
"github.com/kava-labs/kava/x/bep3"
|
||||
v0_8bep3 "github.com/kava-labs/kava/x/bep3/legacy/v0_9"
|
||||
"github.com/kava-labs/kava/x/cdp"
|
||||
"github.com/kava-labs/kava/x/committee"
|
||||
"github.com/kava-labs/kava/x/incentive"
|
||||
@ -108,23 +108,23 @@ func addAuctionState(cdc *codec.Codec, appState genutil.AppMap) {
|
||||
}
|
||||
|
||||
func addBep3State(cdc *codec.Codec, appState genutil.AppMap) {
|
||||
appState[bep3.ModuleName] = cdc.MustMarshalJSON(bep3.NewGenesisState(
|
||||
bep3.NewParams(
|
||||
appState[v0_8bep3.ModuleName] = cdc.MustMarshalJSON(v0_8bep3.NewGenesisState(
|
||||
v0_8bep3.NewParams(
|
||||
mustAccAddressFromBech32(deputyAddressBech32),
|
||||
bep3.DefaultBnbDeputyFixedFee,
|
||||
bep3.DefaultMinAmount,
|
||||
bep3.DefaultMaxAmount,
|
||||
bep3.DefaultMinBlockLock,
|
||||
bep3.DefaultMaxBlockLock,
|
||||
bep3.AssetParams{{
|
||||
v0_8bep3.DefaultBnbDeputyFixedFee,
|
||||
v0_8bep3.DefaultMinAmount,
|
||||
v0_8bep3.DefaultMaxAmount,
|
||||
v0_8bep3.DefaultMinBlockLock,
|
||||
v0_8bep3.DefaultMaxBlockLock,
|
||||
v0_8bep3.AssetParams{{
|
||||
Denom: bnbDenom,
|
||||
CoinID: 714,
|
||||
Limit: sdk.NewInt(4_000_000_000_000),
|
||||
Active: true,
|
||||
}},
|
||||
),
|
||||
bep3.AtomicSwaps{},
|
||||
bep3.AssetSupplies{},
|
||||
v0_8bep3.AtomicSwaps{},
|
||||
v0_8bep3.AssetSupplies{},
|
||||
))
|
||||
}
|
||||
|
||||
@ -203,8 +203,8 @@ func addCommitteeState(cdc *codec.Codec, appState genutil.AppMap) {
|
||||
Key: string(auction.KeyIncrementCollateral),
|
||||
},
|
||||
{
|
||||
Subspace: bep3.ModuleName,
|
||||
Key: string(bep3.KeySupportedAssets),
|
||||
Subspace: v0_8bep3.ModuleName,
|
||||
Key: string(v0_8bep3.KeySupportedAssets),
|
||||
},
|
||||
{
|
||||
Subspace: cdp.ModuleName,
|
||||
|
68
migrate/v0_11/migrate.go
Normal file
68
migrate/v0_11/migrate.go
Normal file
@ -0,0 +1,68 @@
|
||||
package v0_11
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
v0_11bep3 "github.com/kava-labs/kava/x/bep3/legacy/v0_11"
|
||||
v0_9bep3 "github.com/kava-labs/kava/x/bep3/legacy/v0_9"
|
||||
)
|
||||
|
||||
// MigrateBep3 migrates from a v0.9 (or v0.10) bep3 genesis state to a v0.11 bep3 genesis state
|
||||
func MigrateBep3(oldGenState v0_9bep3.GenesisState) v0_11bep3.GenesisState {
|
||||
var assetParams v0_11bep3.AssetParams
|
||||
v0_9Params := oldGenState.Params
|
||||
|
||||
for _, asset := range v0_9Params.SupportedAssets {
|
||||
v10AssetParam := v0_11bep3.AssetParam{
|
||||
Active: asset.Active,
|
||||
Denom: asset.Denom,
|
||||
CoinID: asset.CoinID,
|
||||
DeputyAddress: v0_9Params.BnbDeputyAddress,
|
||||
FixedFee: v0_9Params.BnbDeputyFixedFee,
|
||||
MinSwapAmount: v0_9Params.MinAmount,
|
||||
MaxSwapAmount: v0_9Params.MaxAmount,
|
||||
MinBlockLock: v0_9Params.MinBlockLock,
|
||||
MaxBlockLock: v0_9Params.MaxBlockLock,
|
||||
SupplyLimit: v0_11bep3.AssetSupply{
|
||||
SupplyLimit: sdk.NewCoin(asset.Denom, sdk.ZeroInt()),
|
||||
CurrentSupply: sdk.NewCoin(asset.Denom, sdk.ZeroInt()),
|
||||
IncomingSupply: sdk.NewCoin(asset.Denom, sdk.ZeroInt()),
|
||||
OutgoingSupply: sdk.NewCoin(asset.Denom, sdk.ZeroInt()),
|
||||
},
|
||||
}
|
||||
assetParams = append(assetParams, v10AssetParam)
|
||||
}
|
||||
for _, supply := range oldGenState.AssetSupplies {
|
||||
for _, asset := range assetParams {
|
||||
if asset.Denom == supply.Denom {
|
||||
asset.SupplyLimit.SupplyLimit = supply.SupplyLimit
|
||||
asset.SupplyLimit.CurrentSupply = supply.CurrentSupply
|
||||
asset.SupplyLimit.IncomingSupply = supply.IncomingSupply
|
||||
asset.SupplyLimit.OutgoingSupply = supply.OutgoingSupply
|
||||
}
|
||||
}
|
||||
}
|
||||
var swaps v0_11bep3.AtomicSwaps
|
||||
for _, oldSwap := range oldGenState.AtomicSwaps {
|
||||
newSwap := v0_11bep3.AtomicSwap{
|
||||
Amount: oldSwap.Amount,
|
||||
RandomNumberHash: oldSwap.RandomNumberHash,
|
||||
ExpireHeight: oldSwap.ExpireHeight,
|
||||
Timestamp: oldSwap.Timestamp,
|
||||
Sender: oldSwap.Sender,
|
||||
Recipient: oldSwap.Recipient,
|
||||
SenderOtherChain: oldSwap.SenderOtherChain,
|
||||
RecipientOtherChain: oldSwap.RecipientOtherChain,
|
||||
ClosedBlock: oldSwap.ClosedBlock,
|
||||
Status: v0_11bep3.SwapStatus(oldSwap.Status),
|
||||
CrossChain: oldSwap.CrossChain,
|
||||
Direction: v0_11bep3.SwapDirection(oldSwap.Direction),
|
||||
}
|
||||
swaps = append(swaps, newSwap)
|
||||
}
|
||||
return v0_11bep3.GenesisState{
|
||||
Params: v0_11bep3.Params{
|
||||
AssetParams: assetParams},
|
||||
AtomicSwaps: swaps,
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@ import (
|
||||
v032tendermint "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_32"
|
||||
v033tendermint "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_33"
|
||||
"github.com/kava-labs/kava/x/auction"
|
||||
"github.com/kava-labs/kava/x/bep3"
|
||||
v0_8bep3 "github.com/kava-labs/kava/x/bep3/legacy/v0_9"
|
||||
"github.com/kava-labs/kava/x/cdp"
|
||||
"github.com/kava-labs/kava/x/committee"
|
||||
"github.com/kava-labs/kava/x/incentive"
|
||||
@ -90,7 +90,7 @@ func MigrateAppState(v0_3AppState v038genutil.AppMap) v038genutil.AppMap {
|
||||
|
||||
// migrate new modules (by adding new gen states)
|
||||
v0_8AppState[auction.ModuleName] = v0_8Codec.MustMarshalJSON(auction.DefaultGenesisState())
|
||||
v0_8AppState[bep3.ModuleName] = v0_8Codec.MustMarshalJSON(bep3.DefaultGenesisState())
|
||||
v0_8AppState[v0_8bep3.ModuleName] = v0_8Codec.MustMarshalJSON(v0_8bep3.DefaultGenesisState())
|
||||
v0_8AppState[cdp.ModuleName] = v0_8Codec.MustMarshalJSON(cdp.DefaultGenesisState())
|
||||
v0_8AppState[committee.ModuleName] = v0_8Codec.MustMarshalJSON(committee.DefaultGenesisState())
|
||||
v0_8AppState[incentive.ModuleName] = v0_8Codec.MustMarshalJSON(incentive.DefaultGenesisState())
|
||||
|
@ -9,7 +9,4 @@ import (
|
||||
func BeginBlocker(ctx sdk.Context, k Keeper) {
|
||||
k.UpdateExpiredAtomicSwaps(ctx)
|
||||
k.DeleteClosedAtomicSwapsFromLongtermStorage(ctx)
|
||||
if ctx.BlockTime().After(SupplyLimitUpgradeTime) {
|
||||
k.UpdateAssetSupplies(ctx)
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package bep3_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
@ -31,14 +30,14 @@ func (suite *ABCITestSuite) SetupTest() {
|
||||
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
||||
|
||||
// Set up auth GenesisState
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(11)
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(12)
|
||||
coins := []sdk.Coins{}
|
||||
for j := 0; j < 11; j++ {
|
||||
for j := 0; j < 12; j++ {
|
||||
coins = append(coins, cs(c("bnb", 10000000000), c("ukava", 10000000000)))
|
||||
}
|
||||
authGS := app.NewAuthGenState(addrs, coins)
|
||||
// Initialize test app
|
||||
tApp.InitializeFromGenesisStates(authGS, NewBep3GenStateMulti(addrs[0]))
|
||||
tApp.InitializeFromGenesisStates(authGS, NewBep3GenStateMulti(addrs[11]))
|
||||
|
||||
suite.ctx = ctx
|
||||
suite.app = tApp
|
||||
@ -61,12 +60,12 @@ func (suite *ABCITestSuite) ResetKeeper() {
|
||||
|
||||
// Create atomic swap and check err to confirm creation
|
||||
err := suite.keeper.CreateAtomicSwap(suite.ctx, randomNumberHash, timestamp, expireHeight,
|
||||
suite.addrs[0], suite.addrs[i], TestSenderOtherChain, TestRecipientOtherChain,
|
||||
suite.addrs[11], suite.addrs[i], TestSenderOtherChain, TestRecipientOtherChain,
|
||||
amount, true)
|
||||
suite.Nil(err)
|
||||
|
||||
// Store swap's calculated ID and secret random number
|
||||
swapID := bep3.CalculateSwapID(randomNumberHash, suite.addrs[0], TestSenderOtherChain)
|
||||
swapID := bep3.CalculateSwapID(randomNumberHash, suite.addrs[11], TestSenderOtherChain)
|
||||
swapIDs = append(swapIDs, swapID)
|
||||
randomNumbers = append(randomNumbers, randomNumber[:])
|
||||
}
|
||||
@ -240,61 +239,6 @@ func (suite *ABCITestSuite) TestBeginBlocker_DeleteClosedAtomicSwapsFromLongterm
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *ABCITestSuite) TestBeginBlocker_UpdateAssetSupplies() {
|
||||
// set new asset limit in the params
|
||||
newBnbLimit := c("bnb", 100)
|
||||
params := suite.keeper.GetParams(suite.ctx)
|
||||
for i := range params.SupportedAssets {
|
||||
if params.SupportedAssets[i].Denom != newBnbLimit.Denom {
|
||||
continue
|
||||
}
|
||||
params.SupportedAssets[i].Limit = newBnbLimit.Amount
|
||||
}
|
||||
suite.keeper.SetParams(suite.ctx, params)
|
||||
|
||||
// store the old limit for future reference
|
||||
supply, found := suite.keeper.GetAssetSupply(suite.ctx, []byte(newBnbLimit.Denom))
|
||||
suite.True(found)
|
||||
oldBnbLimit := supply.SupplyLimit
|
||||
|
||||
// run before the upgrade time, check limit was not changed
|
||||
bep3.BeginBlocker(suite.ctx.WithBlockTime(bep3.SupplyLimitUpgradeTime.Add(-time.Hour)), suite.keeper)
|
||||
|
||||
supply, found = suite.keeper.GetAssetSupply(suite.ctx, []byte(newBnbLimit.Denom))
|
||||
suite.True(found)
|
||||
suite.True(supply.SupplyLimit.IsEqual(oldBnbLimit))
|
||||
|
||||
// run at precise upgrade time, check limit was not changed
|
||||
bep3.BeginBlocker(suite.ctx.WithBlockTime(bep3.SupplyLimitUpgradeTime), suite.keeper)
|
||||
|
||||
supply, found = suite.keeper.GetAssetSupply(suite.ctx, []byte(newBnbLimit.Denom))
|
||||
suite.True(found)
|
||||
suite.True(supply.SupplyLimit.IsEqual(oldBnbLimit))
|
||||
|
||||
// run after upgrade time, check limit was changed
|
||||
bep3.BeginBlocker(suite.ctx.WithBlockTime(bep3.SupplyLimitUpgradeTime.Add(time.Nanosecond)), suite.keeper)
|
||||
|
||||
supply, found = suite.keeper.GetAssetSupply(suite.ctx, []byte(newBnbLimit.Denom))
|
||||
suite.True(found)
|
||||
suite.True(supply.SupplyLimit.IsEqual(newBnbLimit))
|
||||
|
||||
// run again with new params, check limit was updated to new param limit
|
||||
finalBnbLimit := c("bnb", 5000000000000)
|
||||
params = suite.keeper.GetParams(suite.ctx)
|
||||
for i := range params.SupportedAssets {
|
||||
if params.SupportedAssets[i].Denom != finalBnbLimit.Denom {
|
||||
continue
|
||||
}
|
||||
params.SupportedAssets[i].Limit = finalBnbLimit.Amount
|
||||
}
|
||||
suite.keeper.SetParams(suite.ctx, params)
|
||||
bep3.BeginBlocker(suite.ctx.WithBlockTime(bep3.SupplyLimitUpgradeTime.Add(time.Hour)), suite.keeper)
|
||||
|
||||
supply, found = suite.keeper.GetAssetSupply(suite.ctx, []byte(newBnbLimit.Denom))
|
||||
suite.True(found)
|
||||
suite.True(supply.SupplyLimit.IsEqual(finalBnbLimit))
|
||||
}
|
||||
|
||||
func TestABCITestSuite(t *testing.T) {
|
||||
suite.Run(t, new(ABCITestSuite))
|
||||
}
|
||||
|
198
x/bep3/alias.go
198
x/bep3/alias.go
@ -1,140 +1,146 @@
|
||||
package bep3
|
||||
|
||||
import (
|
||||
"github.com/kava-labs/kava/x/bep3/client/rest"
|
||||
"github.com/kava-labs/kava/x/bep3/keeper"
|
||||
"github.com/kava-labs/kava/x/bep3/types"
|
||||
)
|
||||
|
||||
// nolint
|
||||
// autogenerated code using github.com/rigelrozanski/multitool
|
||||
// aliases generated for the following subdirectories:
|
||||
// ALIASGEN: github.com/kava-labs/kava/x/bep3/keeper
|
||||
// ALIASGEN: github.com/kava-labs/kava/x/bep3/types
|
||||
|
||||
const (
|
||||
AddrByteCount = types.AddrByteCount
|
||||
AttributeKeyAmount = types.AttributeKeyAmount
|
||||
AttributeKeyAtomicSwapID = types.AttributeKeyAtomicSwapID
|
||||
AttributeKeyAtomicSwapIDs = types.AttributeKeyAtomicSwapIDs
|
||||
AttributeKeyClaimSender = types.AttributeKeyClaimSender
|
||||
AttributeKeyDirection = types.AttributeKeyDirection
|
||||
AttributeKeyExpireHeight = types.AttributeKeyExpireHeight
|
||||
AttributeKeyRandomNumber = types.AttributeKeyRandomNumber
|
||||
AttributeKeyRandomNumberHash = types.AttributeKeyRandomNumberHash
|
||||
AttributeKeyRecipient = types.AttributeKeyRecipient
|
||||
AttributeKeyRefundSender = types.AttributeKeyRefundSender
|
||||
AttributeKeySender = types.AttributeKeySender
|
||||
AttributeKeySenderOtherChain = types.AttributeKeySenderOtherChain
|
||||
AttributeKeyTimestamp = types.AttributeKeyTimestamp
|
||||
AttributeValueCategory = types.AttributeValueCategory
|
||||
CalcSwapID = types.CalcSwapID
|
||||
ClaimAtomicSwap = types.ClaimAtomicSwap
|
||||
Completed = types.Completed
|
||||
CreateAtomicSwap = types.CreateAtomicSwap
|
||||
DefaultLongtermStorageDuration = types.DefaultLongtermStorageDuration
|
||||
DefaultParamspace = types.DefaultParamspace
|
||||
EventTypeClaimAtomicSwap = types.EventTypeClaimAtomicSwap
|
||||
EventTypeCreateAtomicSwap = types.EventTypeCreateAtomicSwap
|
||||
EventTypeClaimAtomicSwap = types.EventTypeClaimAtomicSwap
|
||||
EventTypeRefundAtomicSwap = types.EventTypeRefundAtomicSwap
|
||||
EventTypeSwapsExpired = types.EventTypeSwapsExpired
|
||||
Expired = types.Expired
|
||||
INVALID = types.INVALID
|
||||
Incoming = types.Incoming
|
||||
Int64Size = types.Int64Size
|
||||
MaxExpectedIncomeLength = types.MaxExpectedIncomeLength
|
||||
MaxOtherChainAddrLength = types.MaxOtherChainAddrLength
|
||||
AttributeValueCategory = types.AttributeValueCategory
|
||||
AttributeKeySender = types.AttributeKeySender
|
||||
AttributeKeyRecipient = types.AttributeKeyRecipient
|
||||
AttributeKeyAtomicSwapID = types.AttributeKeyAtomicSwapID
|
||||
AttributeKeyRandomNumberHash = types.AttributeKeyRandomNumberHash
|
||||
AttributeKeyTimestamp = types.AttributeKeyTimestamp
|
||||
AttributeKeySenderOtherChain = types.AttributeKeySenderOtherChain
|
||||
AttributeKeyExpireHeight = types.AttributeKeyExpireHeight
|
||||
AttributeKeyAmount = types.AttributeKeyAmount
|
||||
AttributeKeyDirection = types.AttributeKeyDirection
|
||||
AttributeKeyClaimSender = types.AttributeKeyClaimSender
|
||||
AttributeKeyRandomNumber = types.AttributeKeyRandomNumber
|
||||
AttributeKeyRefundSender = types.AttributeKeyRefundSender
|
||||
AttributeKeyAtomicSwapIDs = types.AttributeKeyAtomicSwapIDs
|
||||
AttributeExpirationBlock = types.AttributeExpirationBlock
|
||||
ModuleName = types.ModuleName
|
||||
NULL = types.NULL
|
||||
Open = types.Open
|
||||
Outgoing = types.Outgoing
|
||||
StoreKey = types.StoreKey
|
||||
RouterKey = types.RouterKey
|
||||
QuerierRoute = types.QuerierRoute
|
||||
DefaultParamspace = types.DefaultParamspace
|
||||
DefaultLongtermStorageDuration = types.DefaultLongtermStorageDuration
|
||||
CreateAtomicSwap = types.CreateAtomicSwap
|
||||
ClaimAtomicSwap = types.ClaimAtomicSwap
|
||||
RefundAtomicSwap = types.RefundAtomicSwap
|
||||
CalcSwapID = types.CalcSwapID
|
||||
Int64Size = types.Int64Size
|
||||
RandomNumberHashLength = types.RandomNumberHashLength
|
||||
RandomNumberLength = types.RandomNumberLength
|
||||
AddrByteCount = types.AddrByteCount
|
||||
MaxOtherChainAddrLength = types.MaxOtherChainAddrLength
|
||||
SwapIDLength = types.SwapIDLength
|
||||
MaxExpectedIncomeLength = types.MaxExpectedIncomeLength
|
||||
QueryGetAssetSupply = types.QueryGetAssetSupply
|
||||
QueryGetAssetSupplies = types.QueryGetAssetSupplies
|
||||
QueryGetAtomicSwap = types.QueryGetAtomicSwap
|
||||
QueryGetAtomicSwaps = types.QueryGetAtomicSwaps
|
||||
QueryGetParams = types.QueryGetParams
|
||||
RandomNumberHashLength = types.RandomNumberHashLength
|
||||
RandomNumberLength = types.RandomNumberLength
|
||||
RefundAtomicSwap = types.RefundAtomicSwap
|
||||
RouterKey = types.RouterKey
|
||||
StoreKey = types.StoreKey
|
||||
SwapIDLength = types.SwapIDLength
|
||||
NULL = types.NULL
|
||||
Open = types.Open
|
||||
Completed = types.Completed
|
||||
Expired = types.Expired
|
||||
INVALID = types.INVALID
|
||||
Incoming = types.Incoming
|
||||
Outgoing = types.Outgoing
|
||||
)
|
||||
|
||||
var (
|
||||
// functions aliases
|
||||
NewKeeper = keeper.NewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
RegisterRoutes = rest.RegisterRoutes
|
||||
NewAssetSupply = types.NewAssetSupply
|
||||
RegisterCodec = types.RegisterCodec
|
||||
NewGenesisState = types.NewGenesisState
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
GenerateSecureRandomNumber = types.GenerateSecureRandomNumber
|
||||
CalculateRandomHash = types.CalculateRandomHash
|
||||
CalculateSwapID = types.CalculateSwapID
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
DefaultParams = types.DefaultParams
|
||||
ErrAssetNotActive = types.ErrAssetNotActive
|
||||
ErrAssetNotSupported = types.ErrAssetNotSupported
|
||||
ErrAssetSupplyNotFound = types.ErrAssetSupplyNotFound
|
||||
ErrAtomicSwapAlreadyExists = types.ErrAtomicSwapAlreadyExists
|
||||
ErrAtomicSwapNotFound = types.ErrAtomicSwapNotFound
|
||||
ErrExceedsAvailableSupply = types.ErrExceedsAvailableSupply
|
||||
ErrExceedsSupplyLimit = types.ErrExceedsSupplyLimit
|
||||
ErrInvalidClaimSecret = types.ErrInvalidClaimSecret
|
||||
ErrInvalidCurrentSupply = types.ErrInvalidCurrentSupply
|
||||
ErrInvalidHeightSpan = types.ErrInvalidHeightSpan
|
||||
ErrInvalidAmount = types.ErrInvalidAmount
|
||||
ErrInvalidIncomingSupply = types.ErrInvalidIncomingSupply
|
||||
ErrInvalidOutgoingSupply = types.ErrInvalidOutgoingSupply
|
||||
ErrInvalidTimestamp = types.ErrInvalidTimestamp
|
||||
ErrSwapNotClaimable = types.ErrSwapNotClaimable
|
||||
ErrSwapNotRefundable = types.ErrSwapNotRefundable
|
||||
GenerateSecureRandomNumber = types.GenerateSecureRandomNumber
|
||||
GetAtomicSwapByHeightKey = types.GetAtomicSwapByHeightKey
|
||||
NewAssetSupply = types.NewAssetSupply
|
||||
NewAtomicSwap = types.NewAtomicSwap
|
||||
NewGenesisState = types.NewGenesisState
|
||||
NewMsgClaimAtomicSwap = types.NewMsgClaimAtomicSwap
|
||||
NewMsgCreateAtomicSwap = types.NewMsgCreateAtomicSwap
|
||||
NewMsgClaimAtomicSwap = types.NewMsgClaimAtomicSwap
|
||||
NewMsgRefundAtomicSwap = types.NewMsgRefundAtomicSwap
|
||||
NewParams = types.NewParams
|
||||
DefaultParams = types.DefaultParams
|
||||
NewAssetParam = types.NewAssetParam
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
NewQueryAssetSupply = types.NewQueryAssetSupply
|
||||
NewQueryAssetSupplies = types.NewQueryAssetSupplies
|
||||
NewQueryAtomicSwapByID = types.NewQueryAtomicSwapByID
|
||||
NewQueryAtomicSwaps = types.NewQueryAtomicSwaps
|
||||
NewSwapDirectionFromString = types.NewSwapDirectionFromString
|
||||
NewAtomicSwap = types.NewAtomicSwap
|
||||
NewSwapStatusFromString = types.NewSwapStatusFromString
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
RegisterCodec = types.RegisterCodec
|
||||
NewSwapDirectionFromString = types.NewSwapDirectionFromString
|
||||
NewAugmentedAtomicSwap = types.NewAugmentedAtomicSwap
|
||||
|
||||
// variable aliases
|
||||
AssetSupplyKeyPrefix = types.AssetSupplyKeyPrefix
|
||||
AtomicSwapByBlockPrefix = types.AtomicSwapByBlockPrefix
|
||||
AtomicSwapCoinsAccAddr = types.AtomicSwapCoinsAccAddr
|
||||
ModuleCdc = types.ModuleCdc
|
||||
ErrInvalidTimestamp = types.ErrInvalidTimestamp
|
||||
ErrInvalidHeightSpan = types.ErrInvalidHeightSpan
|
||||
ErrInsufficientAmount = types.ErrInsufficientAmount
|
||||
ErrAssetNotSupported = types.ErrAssetNotSupported
|
||||
ErrAssetNotActive = types.ErrAssetNotActive
|
||||
ErrAssetSupplyNotFound = types.ErrAssetSupplyNotFound
|
||||
ErrExceedsSupplyLimit = types.ErrExceedsSupplyLimit
|
||||
ErrExceedsAvailableSupply = types.ErrExceedsAvailableSupply
|
||||
ErrInvalidCurrentSupply = types.ErrInvalidCurrentSupply
|
||||
ErrInvalidIncomingSupply = types.ErrInvalidIncomingSupply
|
||||
ErrInvalidOutgoingSupply = types.ErrInvalidOutgoingSupply
|
||||
ErrInvalidClaimSecret = types.ErrInvalidClaimSecret
|
||||
ErrAtomicSwapAlreadyExists = types.ErrAtomicSwapAlreadyExists
|
||||
ErrAtomicSwapNotFound = types.ErrAtomicSwapNotFound
|
||||
ErrSwapNotRefundable = types.ErrSwapNotRefundable
|
||||
ErrSwapNotClaimable = types.ErrSwapNotClaimable
|
||||
ErrInvalidAmount = types.ErrInvalidAmount
|
||||
ErrInvalidSwapAccount = types.ErrInvalidSwapAccount
|
||||
AtomicSwapKeyPrefix = types.AtomicSwapKeyPrefix
|
||||
AtomicSwapByBlockPrefix = types.AtomicSwapByBlockPrefix
|
||||
AtomicSwapLongtermStoragePrefix = types.AtomicSwapLongtermStoragePrefix
|
||||
AtomicSwapCoinsAccAddr = types.AtomicSwapCoinsAccAddr
|
||||
KeyAssetParams = types.KeyAssetParams
|
||||
DefaultBnbDeputyFixedFee = types.DefaultBnbDeputyFixedFee
|
||||
DefaultMinAmount = types.DefaultMinAmount
|
||||
DefaultMaxAmount = types.DefaultMaxAmount
|
||||
DefaultMaxBlockLock = types.DefaultMaxBlockLock
|
||||
DefaultMinBlockLock = types.DefaultMinBlockLock
|
||||
DefaultSupportedAssets = types.DefaultSupportedAssets
|
||||
KeyBnbDeputyAddress = types.KeyBnbDeputyAddress
|
||||
KeyBnbDeputyFixedFee = types.KeyBnbDeputyFixedFee
|
||||
KeyMinAmount = types.KeyMinAmount
|
||||
KeyMaxAmount = types.KeyMaxAmount
|
||||
KeyMaxBlockLock = types.KeyMaxBlockLock
|
||||
KeyMinBlockLock = types.KeyMinBlockLock
|
||||
KeySupportedAssets = types.KeySupportedAssets
|
||||
ModuleCdc = types.ModuleCdc
|
||||
SupplyLimitUpgradeTime = types.SupplyLimitUpgradeTime
|
||||
DefaultMaxBlockLock = types.DefaultMaxBlockLock
|
||||
)
|
||||
|
||||
type (
|
||||
Keeper = keeper.Keeper
|
||||
AssetParam = types.AssetParam
|
||||
AssetParams = types.AssetParams
|
||||
AssetSupplies = types.AssetSupplies
|
||||
AssetSupply = types.AssetSupply
|
||||
AtomicSwap = types.AtomicSwap
|
||||
AtomicSwaps = types.AtomicSwaps
|
||||
GenesisState = types.GenesisState
|
||||
MsgClaimAtomicSwap = types.MsgClaimAtomicSwap
|
||||
MsgCreateAtomicSwap = types.MsgCreateAtomicSwap
|
||||
MsgRefundAtomicSwap = types.MsgRefundAtomicSwap
|
||||
Params = types.Params
|
||||
QueryAssetSupply = types.QueryAssetSupply
|
||||
QueryAtomicSwapByID = types.QueryAtomicSwapByID
|
||||
QueryAtomicSwaps = types.QueryAtomicSwaps
|
||||
SwapDirection = types.SwapDirection
|
||||
SwapStatus = types.SwapStatus
|
||||
Keeper = keeper.Keeper
|
||||
AssetSupply = types.AssetSupply
|
||||
AssetSupplies = types.AssetSupplies
|
||||
GenesisState = types.GenesisState
|
||||
MsgCreateAtomicSwap = types.MsgCreateAtomicSwap
|
||||
MsgClaimAtomicSwap = types.MsgClaimAtomicSwap
|
||||
MsgRefundAtomicSwap = types.MsgRefundAtomicSwap
|
||||
Params = types.Params
|
||||
AssetParam = types.AssetParam
|
||||
AssetParams = types.AssetParams
|
||||
QueryAssetSupply = types.QueryAssetSupply
|
||||
QueryAssetSupplies = types.QueryAssetSupplies
|
||||
QueryAtomicSwapByID = types.QueryAtomicSwapByID
|
||||
QueryAtomicSwaps = types.QueryAtomicSwaps
|
||||
AtomicSwap = types.AtomicSwap
|
||||
AtomicSwaps = types.AtomicSwaps
|
||||
SwapStatus = types.SwapStatus
|
||||
SwapDirection = types.SwapDirection
|
||||
AugmentedAtomicSwap = types.AugmentedAtomicSwap
|
||||
AugmentedAtomicSwaps = types.AugmentedAtomicSwaps
|
||||
)
|
||||
|
@ -133,7 +133,7 @@ func QueryGetAssetSupplyCmd(queryRoute string, cdc *codec.Codec) *cobra.Command
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
// Prepare query params
|
||||
bz, err := cdc.MarshalJSON(types.NewQueryAssetSupply([]byte(args[0])))
|
||||
bz, err := cdc.MarshalJSON(types.NewQueryAssetSupply(args[0]))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ func queryAssetSupplyHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
|
||||
// Prepare params for querier
|
||||
vars := mux.Vars(r)
|
||||
denom := []byte(vars[restDenom])
|
||||
denom := vars[restDenom]
|
||||
params := types.NewQueryAssetSupply(denom)
|
||||
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
|
@ -21,39 +21,8 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, supplyKeeper types.SupplyKeeper
|
||||
}
|
||||
|
||||
keeper.SetParams(ctx, gs.Params)
|
||||
|
||||
// Initialize supported assets
|
||||
for _, asset := range gs.Params.SupportedAssets {
|
||||
zeroCoin := sdk.NewCoin(asset.Denom, sdk.NewInt(0))
|
||||
supply := NewAssetSupply(asset.Denom, zeroCoin, zeroCoin, zeroCoin, sdk.NewCoin(asset.Denom, asset.Limit))
|
||||
keeper.SetAssetSupply(ctx, supply, []byte(asset.Denom))
|
||||
}
|
||||
|
||||
// Increment an asset's incoming, current, and outgoing supply
|
||||
// It it required that assets are supported but they do not have to be active
|
||||
for _, supply := range gs.AssetSupplies {
|
||||
// Asset must be supported but does not have to be active
|
||||
coin, found := keeper.GetAssetByDenom(ctx, supply.Denom)
|
||||
if !found {
|
||||
panic(fmt.Sprintf("invalid asset supply: %s is not a supported asset", coin.Denom))
|
||||
}
|
||||
if !coin.Limit.Equal(supply.SupplyLimit.Amount) {
|
||||
panic(fmt.Sprintf("supported asset limit %s does not equal asset supply %s", coin.Limit, supply.SupplyLimit.Amount))
|
||||
}
|
||||
|
||||
// Increment current, incoming, and outgoing asset supplies
|
||||
err := keeper.IncrementCurrentAssetSupply(ctx, supply.CurrentSupply)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = keeper.IncrementIncomingAssetSupply(ctx, supply.IncomingSupply)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = keeper.IncrementOutgoingAssetSupply(ctx, supply.OutgoingSupply)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, supply := range gs.Supplies {
|
||||
keeper.SetAssetSupply(ctx, supply, supply.GetDenom())
|
||||
}
|
||||
|
||||
var incomingSupplies sdk.Coins
|
||||
@ -108,16 +77,33 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, supplyKeeper types.SupplyKeeper
|
||||
// Asset's given incoming/outgoing supply much match the amount of coins in incoming/outgoing atomic swaps
|
||||
supplies := keeper.GetAllAssetSupplies(ctx)
|
||||
for _, supply := range supplies {
|
||||
incomingSupply := incomingSupplies.AmountOf(supply.Denom)
|
||||
incomingSupply := incomingSupplies.AmountOf(supply.GetDenom())
|
||||
if !supply.IncomingSupply.Amount.Equal(incomingSupply) {
|
||||
panic(fmt.Sprintf("asset's incoming supply %s does not match amount %s in incoming atomic swaps",
|
||||
supply.IncomingSupply, incomingSupply))
|
||||
}
|
||||
outgoingSupply := outgoingSupplies.AmountOf(supply.Denom)
|
||||
outgoingSupply := outgoingSupplies.AmountOf(supply.GetDenom())
|
||||
if !supply.OutgoingSupply.Amount.Equal(outgoingSupply) {
|
||||
panic(fmt.Sprintf("asset's outgoing supply %s does not match amount %s in outgoing atomic swaps",
|
||||
supply.OutgoingSupply, outgoingSupply))
|
||||
}
|
||||
limit, err := keeper.GetSupplyLimit(ctx, supply.GetDenom())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if supply.CurrentSupply.Amount.GT(limit) {
|
||||
panic(fmt.Sprintf("asset's current supply %s is over the supply limit %s", supply.CurrentSupply, limit))
|
||||
}
|
||||
if supply.IncomingSupply.Amount.GT(limit) {
|
||||
panic(fmt.Sprintf("asset's incoming supply %s is over the supply limit %s", supply.IncomingSupply, limit))
|
||||
}
|
||||
if supply.IncomingSupply.Amount.Add(supply.CurrentSupply.Amount).GT(limit) {
|
||||
panic(fmt.Sprintf("asset's incoming supply + current supply %s is over the supply limit %s", supply.IncomingSupply.Add(supply.CurrentSupply), limit))
|
||||
}
|
||||
if supply.OutgoingSupply.Amount.GT(limit) {
|
||||
panic(fmt.Sprintf("asset's outgoing supply %s is over the supply limit %s", supply.OutgoingSupply, limit))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,6 +111,6 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, supplyKeeper types.SupplyKeeper
|
||||
func ExportGenesis(ctx sdk.Context, k Keeper) (data GenesisState) {
|
||||
params := k.GetParams(ctx)
|
||||
swaps := k.GetAllAtomicSwaps(ctx)
|
||||
assets := k.GetAllAssetSupplies(ctx)
|
||||
return NewGenesisState(params, swaps, assets)
|
||||
supplies := k.GetAllAssetSupplies(ctx)
|
||||
return NewGenesisState(params, swaps, supplies)
|
||||
}
|
||||
|
@ -53,16 +53,16 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
name: "import atomic swaps and asset supplies",
|
||||
genState: func() app.GenesisState {
|
||||
gs := baseGenState(suite.addrs[0])
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(3)
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(2)
|
||||
var swaps bep3.AtomicSwaps
|
||||
var supplies bep3.AssetSupplies
|
||||
for i := 0; i < 3; i++ {
|
||||
for i := 0; i < 2; i++ {
|
||||
swap, supply := loadSwapAndSupply(addrs[i], i)
|
||||
swaps = append(swaps, swap)
|
||||
supplies = append(supplies, supply)
|
||||
}
|
||||
gs.AtomicSwaps = swaps
|
||||
gs.AssetSupplies = supplies
|
||||
gs.Supplies = supplies
|
||||
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
|
||||
},
|
||||
expectPass: true,
|
||||
@ -71,7 +71,7 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
name: "0 deputy fees",
|
||||
genState: func() app.GenesisState {
|
||||
gs := baseGenState(suite.addrs[0])
|
||||
gs.Params.BnbDeputyFixedFee = sdk.ZeroInt()
|
||||
gs.Params.AssetParams[0].FixedFee = sdk.ZeroInt()
|
||||
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
|
||||
},
|
||||
expectPass: true,
|
||||
@ -91,14 +91,12 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
name: "current supply above limit",
|
||||
genState: func() app.GenesisState {
|
||||
gs := baseGenState(suite.addrs[0])
|
||||
assetParam, _ := suite.keeper.GetAssetByDenom(suite.ctx, "bnb")
|
||||
gs.AssetSupplies = bep3.AssetSupplies{
|
||||
assetParam, _ := suite.keeper.GetAsset(suite.ctx, "bnb")
|
||||
gs.Supplies = bep3.AssetSupplies{
|
||||
bep3.AssetSupply{
|
||||
Denom: "bnb",
|
||||
IncomingSupply: c("bnb", 0),
|
||||
OutgoingSupply: c("bnb", 0),
|
||||
CurrentSupply: c("bnb", assetParam.Limit.Add(i(1)).Int64()),
|
||||
SupplyLimit: c("bnb", assetParam.Limit.Int64()),
|
||||
CurrentSupply: c("bnb", assetParam.SupplyLimit.Add(i(1)).Int64()),
|
||||
},
|
||||
}
|
||||
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
|
||||
@ -110,8 +108,8 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
genState: func() app.GenesisState {
|
||||
gs := baseGenState(suite.addrs[0])
|
||||
// Set up overlimit amount
|
||||
assetParam, _ := suite.keeper.GetAssetByDenom(suite.ctx, "bnb")
|
||||
overLimitAmount := assetParam.Limit.Add(i(1))
|
||||
assetParam, _ := suite.keeper.GetAsset(suite.ctx, "bnb")
|
||||
overLimitAmount := assetParam.SupplyLimit.Add(i(1))
|
||||
|
||||
// Set up an atomic swap with amount equal to the currently asset supply
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(2)
|
||||
@ -124,13 +122,11 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
gs.AtomicSwaps = bep3.AtomicSwaps{swap}
|
||||
|
||||
// Set up asset supply with overlimit current supply
|
||||
gs.AssetSupplies = bep3.AssetSupplies{
|
||||
gs.Supplies = bep3.AssetSupplies{
|
||||
bep3.AssetSupply{
|
||||
Denom: "bnb",
|
||||
IncomingSupply: c("bnb", assetParam.Limit.Add(i(1)).Int64()),
|
||||
IncomingSupply: c("bnb", assetParam.SupplyLimit.Add(i(1)).Int64()),
|
||||
OutgoingSupply: c("bnb", 0),
|
||||
CurrentSupply: c("bnb", 0),
|
||||
SupplyLimit: c("bnb", assetParam.Limit.Int64()),
|
||||
},
|
||||
}
|
||||
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
|
||||
@ -142,8 +138,8 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
genState: func() app.GenesisState {
|
||||
gs := baseGenState(suite.addrs[0])
|
||||
// Set up overlimit amount
|
||||
assetParam, _ := suite.keeper.GetAssetByDenom(suite.ctx, "bnb")
|
||||
halfLimit := assetParam.Limit.Int64() / 2
|
||||
assetParam, _ := suite.keeper.GetAsset(suite.ctx, "bnb")
|
||||
halfLimit := assetParam.SupplyLimit.Int64() / 2
|
||||
overHalfLimit := halfLimit + 1
|
||||
|
||||
// Set up an atomic swap with amount equal to the currently asset supply
|
||||
@ -157,13 +153,41 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
gs.AtomicSwaps = bep3.AtomicSwaps{swap}
|
||||
|
||||
// Set up asset supply with overlimit current supply
|
||||
gs.AssetSupplies = bep3.AssetSupplies{
|
||||
gs.Supplies = bep3.AssetSupplies{
|
||||
bep3.AssetSupply{
|
||||
Denom: "bnb",
|
||||
IncomingSupply: c("bnb", halfLimit),
|
||||
OutgoingSupply: c("bnb", 0),
|
||||
CurrentSupply: c("bnb", overHalfLimit),
|
||||
SupplyLimit: c("bnb", assetParam.Limit.Int64()),
|
||||
},
|
||||
}
|
||||
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
|
||||
},
|
||||
expectPass: false,
|
||||
},
|
||||
{
|
||||
name: "outgoing supply above limit",
|
||||
genState: func() app.GenesisState {
|
||||
gs := baseGenState(suite.addrs[0])
|
||||
// Set up overlimit amount
|
||||
assetParam, _ := suite.keeper.GetAsset(suite.ctx, "bnb")
|
||||
overLimitAmount := assetParam.SupplyLimit.Add(i(1))
|
||||
|
||||
// Set up an atomic swap with amount equal to the currently asset supply
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(2)
|
||||
timestamp := ts(0)
|
||||
randomNumber, _ := bep3.GenerateSecureRandomNumber()
|
||||
randomNumberHash := bep3.CalculateRandomHash(randomNumber[:], timestamp)
|
||||
swap := bep3.NewAtomicSwap(cs(c("bnb", overLimitAmount.Int64())), randomNumberHash,
|
||||
bep3.DefaultMinBlockLock, timestamp, addrs[1], suite.addrs[0], TestSenderOtherChain,
|
||||
TestRecipientOtherChain, 0, bep3.Open, true, bep3.Outgoing)
|
||||
gs.AtomicSwaps = bep3.AtomicSwaps{swap}
|
||||
|
||||
// Set up asset supply with overlimit current supply
|
||||
gs.Supplies = bep3.AssetSupplies{
|
||||
bep3.AssetSupply{
|
||||
IncomingSupply: c("bnb", 0),
|
||||
OutgoingSupply: c("bnb", 0),
|
||||
CurrentSupply: c("bnb", assetParam.SupplyLimit.Add(i(1)).Int64()),
|
||||
},
|
||||
}
|
||||
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
|
||||
@ -174,13 +198,11 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
name: "asset supply denom is not a supported asset",
|
||||
genState: func() app.GenesisState {
|
||||
gs := baseGenState(suite.addrs[0])
|
||||
gs.AssetSupplies = bep3.AssetSupplies{
|
||||
gs.Supplies = bep3.AssetSupplies{
|
||||
bep3.AssetSupply{
|
||||
Denom: "fake",
|
||||
IncomingSupply: c("fake", 0),
|
||||
OutgoingSupply: c("fake", 0),
|
||||
CurrentSupply: c("fake", 0),
|
||||
SupplyLimit: c("fake", StandardSupplyLimit.Int64()),
|
||||
},
|
||||
}
|
||||
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
|
||||
@ -225,8 +247,8 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
name: "minimum block lock cannot be > maximum block lock",
|
||||
genState: func() app.GenesisState {
|
||||
gs := baseGenState(suite.addrs[0])
|
||||
gs.Params.MinBlockLock = 201
|
||||
gs.Params.MaxBlockLock = 200
|
||||
gs.Params.AssetParams[0].MinBlockLock = 201
|
||||
gs.Params.AssetParams[0].MaxBlockLock = 200
|
||||
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
|
||||
},
|
||||
expectPass: false,
|
||||
@ -235,7 +257,7 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
name: "empty supported asset denom",
|
||||
genState: func() app.GenesisState {
|
||||
gs := baseGenState(suite.addrs[0])
|
||||
gs.Params.SupportedAssets[0].Denom = ""
|
||||
gs.Params.AssetParams[0].Denom = ""
|
||||
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
|
||||
},
|
||||
expectPass: false,
|
||||
@ -244,7 +266,7 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
name: "negative supported asset limit",
|
||||
genState: func() app.GenesisState {
|
||||
gs := baseGenState(suite.addrs[0])
|
||||
gs.Params.SupportedAssets[0].Limit = i(-100)
|
||||
gs.Params.AssetParams[0].SupplyLimit = i(-100)
|
||||
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
|
||||
},
|
||||
expectPass: false,
|
||||
@ -253,7 +275,7 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
name: "duplicate supported asset denom",
|
||||
genState: func() app.GenesisState {
|
||||
gs := baseGenState(suite.addrs[0])
|
||||
gs.Params.SupportedAssets[1].Denom = "bnb"
|
||||
gs.Params.AssetParams[1].Denom = "bnb"
|
||||
return app.GenesisState{"bep3": bep3.ModuleCdc.MustMarshalJSON(gs)}
|
||||
},
|
||||
expectPass: false,
|
||||
@ -261,15 +283,18 @@ func (suite *GenesisTestSuite) TestGenesisState() {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
if tc.expectPass {
|
||||
suite.NotPanics(func() {
|
||||
suite.app.InitializeFromGenesisStates(tc.genState())
|
||||
}, tc.name)
|
||||
} else {
|
||||
suite.Panics(func() {
|
||||
suite.app.InitializeFromGenesisStates(tc.genState())
|
||||
}, tc.name)
|
||||
}
|
||||
suite.Run(tc.name, func() {
|
||||
if tc.expectPass {
|
||||
suite.NotPanics(func() {
|
||||
suite.app.InitializeFromGenesisStates(tc.genState())
|
||||
}, tc.name)
|
||||
} else {
|
||||
suite.Panics(func() {
|
||||
suite.app.InitializeFromGenesisStates(tc.genState())
|
||||
}, tc.name)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ const (
|
||||
|
||||
var (
|
||||
StandardSupplyLimit = i(100000000000)
|
||||
DenomMap = map[int]string{0: "btc", 1: "eth", 2: "bnb", 3: "xrp", 4: "dai"}
|
||||
DenomMap = map[int]string{0: "bnb", 1: "inc"}
|
||||
)
|
||||
|
||||
func i(in int64) sdk.Int { return sdk.NewInt(in) }
|
||||
@ -35,41 +35,48 @@ func NewBep3GenStateMulti(deputy sdk.AccAddress) app.GenesisState {
|
||||
}
|
||||
|
||||
func baseGenState(deputy sdk.AccAddress) bep3.GenesisState {
|
||||
|
||||
bep3Genesis := bep3.GenesisState{
|
||||
Params: bep3.Params{
|
||||
BnbDeputyAddress: deputy,
|
||||
BnbDeputyFixedFee: bep3.DefaultBnbDeputyFixedFee, // 1,000
|
||||
MinAmount: bep3.DefaultMinAmount, // 0
|
||||
MaxAmount: bep3.DefaultMaxAmount, // 10,000
|
||||
MinBlockLock: bep3.DefaultMinBlockLock, // 220
|
||||
MaxBlockLock: bep3.DefaultMaxBlockLock, // 270
|
||||
SupportedAssets: bep3.AssetParams{
|
||||
AssetParams: bep3.AssetParams{
|
||||
bep3.AssetParam{
|
||||
Denom: "btc",
|
||||
CoinID: 714,
|
||||
Limit: StandardSupplyLimit,
|
||||
Active: true,
|
||||
Denom: "bnb",
|
||||
CoinID: 714,
|
||||
SupplyLimit: sdk.NewInt(350000000000000),
|
||||
Active: true,
|
||||
DeputyAddress: deputy,
|
||||
FixedFee: sdk.NewInt(1000),
|
||||
MinSwapAmount: sdk.OneInt(),
|
||||
MaxSwapAmount: sdk.NewInt(1000000000000),
|
||||
MinBlockLock: bep3.DefaultMinBlockLock,
|
||||
MaxBlockLock: bep3.DefaultMaxBlockLock,
|
||||
},
|
||||
bep3.AssetParam{
|
||||
Denom: "eth",
|
||||
CoinID: 999999,
|
||||
Limit: StandardSupplyLimit,
|
||||
Active: true,
|
||||
},
|
||||
bep3.AssetParam{
|
||||
Denom: "bnb",
|
||||
CoinID: 99999,
|
||||
Limit: StandardSupplyLimit,
|
||||
Active: true,
|
||||
},
|
||||
bep3.AssetParam{
|
||||
Denom: "inc",
|
||||
CoinID: 9999,
|
||||
Limit: i(100),
|
||||
Active: false,
|
||||
Denom: "inc",
|
||||
CoinID: 9999,
|
||||
SupplyLimit: sdk.NewInt(100000000000),
|
||||
Active: true,
|
||||
DeputyAddress: deputy,
|
||||
FixedFee: sdk.NewInt(1000),
|
||||
MinSwapAmount: sdk.OneInt(),
|
||||
MaxSwapAmount: sdk.NewInt(1000000000000),
|
||||
MinBlockLock: bep3.DefaultMinBlockLock,
|
||||
MaxBlockLock: bep3.DefaultMaxBlockLock,
|
||||
},
|
||||
},
|
||||
},
|
||||
Supplies: bep3.AssetSupplies{
|
||||
bep3.NewAssetSupply(
|
||||
sdk.NewCoin("bnb", sdk.ZeroInt()),
|
||||
sdk.NewCoin("bnb", sdk.ZeroInt()),
|
||||
sdk.NewCoin("bnb", sdk.ZeroInt()),
|
||||
),
|
||||
bep3.NewAssetSupply(
|
||||
sdk.NewCoin("inc", sdk.ZeroInt()),
|
||||
sdk.NewCoin("inc", sdk.ZeroInt()),
|
||||
sdk.NewCoin("inc", sdk.ZeroInt()),
|
||||
),
|
||||
},
|
||||
}
|
||||
return bep3Genesis
|
||||
}
|
||||
@ -84,8 +91,8 @@ func loadSwapAndSupply(addr sdk.AccAddress, index int) (bep3.AtomicSwap, bep3.As
|
||||
expireOffset, timestamp, addr, addr, TestSenderOtherChain,
|
||||
TestRecipientOtherChain, 1, bep3.Open, true, bep3.Incoming)
|
||||
|
||||
supply := bep3.NewAssetSupply(coin.Denom, coin, c(coin.Denom, 0),
|
||||
c(coin.Denom, 0), c(coin.Denom, StandardSupplyLimit.Int64()))
|
||||
supply := bep3.NewAssetSupply(coin, c(coin.Denom, 0),
|
||||
c(coin.Denom, 0))
|
||||
|
||||
return swap, supply
|
||||
}
|
||||
|
@ -9,24 +9,30 @@ import (
|
||||
|
||||
// IncrementCurrentAssetSupply increments an asset's supply by the coin
|
||||
func (k Keeper) IncrementCurrentAssetSupply(ctx sdk.Context, coin sdk.Coin) error {
|
||||
supply, found := k.GetAssetSupply(ctx, []byte(coin.Denom))
|
||||
supply, found := k.GetAssetSupply(ctx, coin.Denom)
|
||||
if !found {
|
||||
return sdkerrors.Wrap(types.ErrAssetNotSupported, coin.Denom)
|
||||
}
|
||||
|
||||
limit, err := k.GetSupplyLimit(ctx, coin.Denom)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
supplyLimit := sdk.NewCoin(coin.Denom, limit)
|
||||
|
||||
// Resulting current supply must be under asset's limit
|
||||
if supply.SupplyLimit.IsLT(supply.CurrentSupply.Add(coin)) {
|
||||
return sdkerrors.Wrapf(types.ErrExceedsSupplyLimit, "increase %s, asset supply %s, limit %s", coin, supply.CurrentSupply, supply.SupplyLimit)
|
||||
if supplyLimit.IsLT(supply.CurrentSupply.Add(coin)) {
|
||||
return sdkerrors.Wrapf(types.ErrExceedsSupplyLimit, "increase %s, asset supply %s, limit %s", coin, supply.CurrentSupply, supplyLimit)
|
||||
}
|
||||
|
||||
supply.CurrentSupply = supply.CurrentSupply.Add(coin)
|
||||
k.SetAssetSupply(ctx, supply, []byte(coin.Denom))
|
||||
k.SetAssetSupply(ctx, supply, coin.Denom)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DecrementCurrentAssetSupply decrement an asset's supply by the coin
|
||||
func (k Keeper) DecrementCurrentAssetSupply(ctx sdk.Context, coin sdk.Coin) error {
|
||||
supply, found := k.GetAssetSupply(ctx, []byte(coin.Denom))
|
||||
supply, found := k.GetAssetSupply(ctx, coin.Denom)
|
||||
if !found {
|
||||
return sdkerrors.Wrap(types.ErrAssetNotSupported, coin.Denom)
|
||||
}
|
||||
@ -38,31 +44,37 @@ func (k Keeper) DecrementCurrentAssetSupply(ctx sdk.Context, coin sdk.Coin) erro
|
||||
}
|
||||
|
||||
supply.CurrentSupply = supply.CurrentSupply.Sub(coin)
|
||||
k.SetAssetSupply(ctx, supply, []byte(coin.Denom))
|
||||
k.SetAssetSupply(ctx, supply, coin.Denom)
|
||||
return nil
|
||||
}
|
||||
|
||||
// IncrementIncomingAssetSupply increments an asset's incoming supply
|
||||
func (k Keeper) IncrementIncomingAssetSupply(ctx sdk.Context, coin sdk.Coin) error {
|
||||
supply, found := k.GetAssetSupply(ctx, []byte(coin.Denom))
|
||||
supply, found := k.GetAssetSupply(ctx, coin.Denom)
|
||||
if !found {
|
||||
return sdkerrors.Wrap(types.ErrAssetNotSupported, coin.Denom)
|
||||
}
|
||||
|
||||
// Result of (current + incoming + amount) must be under asset's limit
|
||||
totalSupply := supply.CurrentSupply.Add(supply.IncomingSupply)
|
||||
if supply.SupplyLimit.IsLT(totalSupply.Add(coin)) {
|
||||
return sdkerrors.Wrapf(types.ErrExceedsSupplyLimit, "increase %s, asset supply %s, limit %s", coin, totalSupply, supply.SupplyLimit)
|
||||
|
||||
limit, err := k.GetSupplyLimit(ctx, coin.Denom)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
supplyLimit := sdk.NewCoin(coin.Denom, limit)
|
||||
if supplyLimit.IsLT(totalSupply.Add(coin)) {
|
||||
return sdkerrors.Wrapf(types.ErrExceedsSupplyLimit, "increase %s, asset supply %s, limit %s", coin, totalSupply, supplyLimit)
|
||||
}
|
||||
|
||||
supply.IncomingSupply = supply.IncomingSupply.Add(coin)
|
||||
k.SetAssetSupply(ctx, supply, []byte(coin.Denom))
|
||||
k.SetAssetSupply(ctx, supply, coin.Denom)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DecrementIncomingAssetSupply decrements an asset's incoming supply
|
||||
func (k Keeper) DecrementIncomingAssetSupply(ctx sdk.Context, coin sdk.Coin) error {
|
||||
supply, found := k.GetAssetSupply(ctx, []byte(coin.Denom))
|
||||
supply, found := k.GetAssetSupply(ctx, coin.Denom)
|
||||
if !found {
|
||||
return sdkerrors.Wrap(types.ErrAssetNotSupported, coin.Denom)
|
||||
}
|
||||
@ -74,13 +86,13 @@ func (k Keeper) DecrementIncomingAssetSupply(ctx sdk.Context, coin sdk.Coin) err
|
||||
}
|
||||
|
||||
supply.IncomingSupply = supply.IncomingSupply.Sub(coin)
|
||||
k.SetAssetSupply(ctx, supply, []byte(coin.Denom))
|
||||
k.SetAssetSupply(ctx, supply, coin.Denom)
|
||||
return nil
|
||||
}
|
||||
|
||||
// IncrementOutgoingAssetSupply increments an asset's outoing supply
|
||||
// IncrementOutgoingAssetSupply increments an asset's outgoing supply
|
||||
func (k Keeper) IncrementOutgoingAssetSupply(ctx sdk.Context, coin sdk.Coin) error {
|
||||
supply, found := k.GetAssetSupply(ctx, []byte(coin.Denom))
|
||||
supply, found := k.GetAssetSupply(ctx, coin.Denom)
|
||||
if !found {
|
||||
return sdkerrors.Wrap(types.ErrAssetNotSupported, coin.Denom)
|
||||
}
|
||||
@ -92,13 +104,13 @@ func (k Keeper) IncrementOutgoingAssetSupply(ctx sdk.Context, coin sdk.Coin) err
|
||||
}
|
||||
|
||||
supply.OutgoingSupply = supply.OutgoingSupply.Add(coin)
|
||||
k.SetAssetSupply(ctx, supply, []byte(coin.Denom))
|
||||
k.SetAssetSupply(ctx, supply, coin.Denom)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DecrementOutgoingAssetSupply decrements an asset's outoing supply
|
||||
// DecrementOutgoingAssetSupply decrements an asset's outgoing supply
|
||||
func (k Keeper) DecrementOutgoingAssetSupply(ctx sdk.Context, coin sdk.Coin) error {
|
||||
supply, found := k.GetAssetSupply(ctx, []byte(coin.Denom))
|
||||
supply, found := k.GetAssetSupply(ctx, coin.Denom)
|
||||
if !found {
|
||||
return sdkerrors.Wrap(types.ErrAssetNotSupported, coin.Denom)
|
||||
}
|
||||
@ -110,21 +122,6 @@ func (k Keeper) DecrementOutgoingAssetSupply(ctx sdk.Context, coin sdk.Coin) err
|
||||
}
|
||||
|
||||
supply.OutgoingSupply = supply.OutgoingSupply.Sub(coin)
|
||||
k.SetAssetSupply(ctx, supply, []byte(coin.Denom))
|
||||
k.SetAssetSupply(ctx, supply, coin.Denom)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateAssetSupplies applies updates to the asset limit from parameters to the asset supplies
|
||||
func (k Keeper) UpdateAssetSupplies(ctx sdk.Context) {
|
||||
params := k.GetParams(ctx)
|
||||
for _, supportedAsset := range params.SupportedAssets {
|
||||
asset, found := k.GetAssetSupply(ctx, []byte(supportedAsset.Denom))
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
if !asset.SupplyLimit.Amount.Equal(supportedAsset.Limit) {
|
||||
asset.SupplyLimit = sdk.NewCoin(supportedAsset.Denom, supportedAsset.Limit)
|
||||
k.SetAssetSupply(ctx, asset, []byte(supportedAsset.Denom))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,16 +36,16 @@ func (suite *AssetTestSuite) SetupTest() {
|
||||
tApp.InitializeFromGenesisStates(NewBep3GenStateMulti(deputy))
|
||||
|
||||
keeper := tApp.GetBep3Keeper()
|
||||
|
||||
params := keeper.GetParams(ctx)
|
||||
params.AssetParams[0].SupplyLimit = sdk.NewInt(50)
|
||||
keeper.SetParams(ctx, params)
|
||||
// Set asset supply with standard value for testing
|
||||
supply := types.AssetSupply{
|
||||
Denom: "bnb",
|
||||
IncomingSupply: c("bnb", 5),
|
||||
OutgoingSupply: c("bnb", 5),
|
||||
CurrentSupply: c("bnb", 40),
|
||||
SupplyLimit: c("bnb", 50),
|
||||
}
|
||||
keeper.SetAssetSupply(ctx, supply, []byte(supply.Denom))
|
||||
keeper.SetAssetSupply(ctx, supply, supply.GetDenom())
|
||||
|
||||
suite.app = tApp
|
||||
suite.ctx = ctx
|
||||
@ -95,11 +95,10 @@ func (suite *AssetTestSuite) TestIncrementCurrentAssetSupply() {
|
||||
for _, tc := range testCases {
|
||||
suite.SetupTest()
|
||||
suite.Run(tc.name, func() {
|
||||
supplyKeyPrefix := []byte(tc.args.coin.Denom)
|
||||
|
||||
preSupply, found := suite.keeper.GetAssetSupply(suite.ctx, supplyKeyPrefix)
|
||||
preSupply, found := suite.keeper.GetAssetSupply(suite.ctx, tc.args.coin.Denom)
|
||||
err := suite.keeper.IncrementCurrentAssetSupply(suite.ctx, tc.args.coin)
|
||||
postSupply, _ := suite.keeper.GetAssetSupply(suite.ctx, supplyKeyPrefix)
|
||||
postSupply, _ := suite.keeper.GetAssetSupply(suite.ctx, tc.args.coin.Denom)
|
||||
|
||||
if tc.expectPass {
|
||||
suite.True(found)
|
||||
@ -155,11 +154,10 @@ func (suite *AssetTestSuite) TestDecrementCurrentAssetSupply() {
|
||||
for _, tc := range testCases {
|
||||
suite.SetupTest()
|
||||
suite.Run(tc.name, func() {
|
||||
supplyKeyPrefix := []byte(tc.args.coin.Denom)
|
||||
|
||||
preSupply, found := suite.keeper.GetAssetSupply(suite.ctx, supplyKeyPrefix)
|
||||
preSupply, found := suite.keeper.GetAssetSupply(suite.ctx, tc.args.coin.Denom)
|
||||
err := suite.keeper.DecrementCurrentAssetSupply(suite.ctx, tc.args.coin)
|
||||
postSupply, _ := suite.keeper.GetAssetSupply(suite.ctx, supplyKeyPrefix)
|
||||
postSupply, _ := suite.keeper.GetAssetSupply(suite.ctx, tc.args.coin.Denom)
|
||||
|
||||
if tc.expectPass {
|
||||
suite.True(found)
|
||||
@ -215,11 +213,9 @@ func (suite *AssetTestSuite) TestIncrementIncomingAssetSupply() {
|
||||
for _, tc := range testCases {
|
||||
suite.SetupTest()
|
||||
suite.Run(tc.name, func() {
|
||||
supplyKeyPrefix := []byte(tc.args.coin.Denom)
|
||||
|
||||
preSupply, found := suite.keeper.GetAssetSupply(suite.ctx, supplyKeyPrefix)
|
||||
preSupply, found := suite.keeper.GetAssetSupply(suite.ctx, tc.args.coin.Denom)
|
||||
err := suite.keeper.IncrementIncomingAssetSupply(suite.ctx, tc.args.coin)
|
||||
postSupply, _ := suite.keeper.GetAssetSupply(suite.ctx, supplyKeyPrefix)
|
||||
postSupply, _ := suite.keeper.GetAssetSupply(suite.ctx, tc.args.coin.Denom)
|
||||
|
||||
if tc.expectPass {
|
||||
suite.True(found)
|
||||
@ -275,11 +271,10 @@ func (suite *AssetTestSuite) TestDecrementIncomingAssetSupply() {
|
||||
for _, tc := range testCases {
|
||||
suite.SetupTest()
|
||||
suite.Run(tc.name, func() {
|
||||
supplyKeyPrefix := []byte(tc.args.coin.Denom)
|
||||
|
||||
preSupply, found := suite.keeper.GetAssetSupply(suite.ctx, supplyKeyPrefix)
|
||||
preSupply, found := suite.keeper.GetAssetSupply(suite.ctx, tc.args.coin.Denom)
|
||||
err := suite.keeper.DecrementIncomingAssetSupply(suite.ctx, tc.args.coin)
|
||||
postSupply, _ := suite.keeper.GetAssetSupply(suite.ctx, supplyKeyPrefix)
|
||||
postSupply, _ := suite.keeper.GetAssetSupply(suite.ctx, tc.args.coin.Denom)
|
||||
|
||||
if tc.expectPass {
|
||||
suite.True(found)
|
||||
@ -335,11 +330,10 @@ func (suite *AssetTestSuite) TestIncrementOutgoingAssetSupply() {
|
||||
for _, tc := range testCases {
|
||||
suite.SetupTest()
|
||||
suite.Run(tc.name, func() {
|
||||
supplyKeyPrefix := []byte(tc.args.coin.Denom)
|
||||
|
||||
preSupply, found := suite.keeper.GetAssetSupply(suite.ctx, supplyKeyPrefix)
|
||||
preSupply, found := suite.keeper.GetAssetSupply(suite.ctx, tc.args.coin.Denom)
|
||||
err := suite.keeper.IncrementOutgoingAssetSupply(suite.ctx, tc.args.coin)
|
||||
postSupply, _ := suite.keeper.GetAssetSupply(suite.ctx, supplyKeyPrefix)
|
||||
postSupply, _ := suite.keeper.GetAssetSupply(suite.ctx, tc.args.coin.Denom)
|
||||
|
||||
if tc.expectPass {
|
||||
suite.True(found)
|
||||
@ -395,11 +389,9 @@ func (suite *AssetTestSuite) TestDecrementOutgoingAssetSupply() {
|
||||
for _, tc := range testCases {
|
||||
suite.SetupTest()
|
||||
suite.Run(tc.name, func() {
|
||||
supplyKeyPrefix := []byte(tc.args.coin.Denom)
|
||||
|
||||
preSupply, found := suite.keeper.GetAssetSupply(suite.ctx, supplyKeyPrefix)
|
||||
preSupply, found := suite.keeper.GetAssetSupply(suite.ctx, tc.args.coin.Denom)
|
||||
err := suite.keeper.DecrementOutgoingAssetSupply(suite.ctx, tc.args.coin)
|
||||
postSupply, _ := suite.keeper.GetAssetSupply(suite.ctx, supplyKeyPrefix)
|
||||
postSupply, _ := suite.keeper.GetAssetSupply(suite.ctx, tc.args.coin.Denom)
|
||||
|
||||
if tc.expectPass {
|
||||
suite.True(found)
|
||||
@ -413,25 +405,6 @@ func (suite *AssetTestSuite) TestDecrementOutgoingAssetSupply() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *AssetTestSuite) TestUpdateAssetSupplies() {
|
||||
// set new asset limit in the params
|
||||
newBnbLimit := c("bnb", 100)
|
||||
params := suite.keeper.GetParams(suite.ctx)
|
||||
for i := range params.SupportedAssets {
|
||||
if params.SupportedAssets[i].Denom != newBnbLimit.Denom {
|
||||
continue
|
||||
}
|
||||
params.SupportedAssets[i].Limit = newBnbLimit.Amount
|
||||
}
|
||||
suite.keeper.SetParams(suite.ctx, params)
|
||||
|
||||
suite.keeper.UpdateAssetSupplies(suite.ctx)
|
||||
|
||||
supply, found := suite.keeper.GetAssetSupply(suite.ctx, []byte(newBnbLimit.Denom))
|
||||
suite.True(found)
|
||||
suite.True(supply.SupplyLimit.IsEqual(newBnbLimit))
|
||||
}
|
||||
|
||||
func TestAssetTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(AssetTestSuite))
|
||||
}
|
||||
|
@ -20,10 +20,9 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
StandardSupplyLimit = i(350000000000000)
|
||||
DenomMap = map[int]string{0: "btc", 1: "eth", 2: "bnb", 3: "xrp", 4: "dai"}
|
||||
TestUser1 = sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser1")))
|
||||
TestUser2 = sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser2")))
|
||||
DenomMap = map[int]string{0: "btc", 1: "eth", 2: "bnb", 3: "xrp", 4: "dai"}
|
||||
TestUser1 = sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser1")))
|
||||
TestUser2 = sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser2")))
|
||||
)
|
||||
|
||||
func i(in int64) sdk.Int { return sdk.NewInt(in) }
|
||||
@ -34,27 +33,45 @@ func ts(minOffset int) int64 { return tmtime.Now().Add(time.Durat
|
||||
func NewBep3GenStateMulti(deputyAddress sdk.AccAddress) app.GenesisState {
|
||||
bep3Genesis := types.GenesisState{
|
||||
Params: bep3.Params{
|
||||
BnbDeputyAddress: deputyAddress,
|
||||
BnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee, // 1000
|
||||
MinAmount: types.DefaultMinAmount, // 0
|
||||
MaxAmount: types.DefaultMaxAmount, // 10,000
|
||||
MinBlockLock: types.DefaultMinBlockLock, // 220
|
||||
MaxBlockLock: types.DefaultMaxBlockLock, // 270
|
||||
SupportedAssets: types.AssetParams{
|
||||
AssetParams: types.AssetParams{
|
||||
types.AssetParam{
|
||||
Denom: "bnb",
|
||||
CoinID: 714,
|
||||
Limit: StandardSupplyLimit,
|
||||
Active: true,
|
||||
Denom: "bnb",
|
||||
CoinID: 714,
|
||||
SupplyLimit: sdk.NewInt(350000000000000),
|
||||
Active: true,
|
||||
DeputyAddress: deputyAddress,
|
||||
FixedFee: sdk.NewInt(1000),
|
||||
MinSwapAmount: sdk.OneInt(),
|
||||
MaxSwapAmount: sdk.NewInt(1000000000000),
|
||||
MinBlockLock: types.DefaultMinBlockLock,
|
||||
MaxBlockLock: types.DefaultMaxBlockLock,
|
||||
},
|
||||
types.AssetParam{
|
||||
Denom: "inc",
|
||||
CoinID: 9999,
|
||||
Limit: i(100),
|
||||
Active: false,
|
||||
Denom: "inc",
|
||||
CoinID: 9999,
|
||||
SupplyLimit: sdk.NewInt(100),
|
||||
Active: false,
|
||||
DeputyAddress: deputyAddress,
|
||||
FixedFee: sdk.NewInt(1000),
|
||||
MinSwapAmount: sdk.OneInt(),
|
||||
MaxSwapAmount: sdk.NewInt(1000000000000),
|
||||
MinBlockLock: types.DefaultMinBlockLock,
|
||||
MaxBlockLock: types.DefaultMaxBlockLock,
|
||||
},
|
||||
},
|
||||
},
|
||||
Supplies: bep3.AssetSupplies{
|
||||
bep3.NewAssetSupply(
|
||||
sdk.NewCoin("bnb", sdk.ZeroInt()),
|
||||
sdk.NewCoin("bnb", sdk.ZeroInt()),
|
||||
sdk.NewCoin("bnb", sdk.ZeroInt()),
|
||||
),
|
||||
bep3.NewAssetSupply(
|
||||
sdk.NewCoin("inc", sdk.ZeroInt()),
|
||||
sdk.NewCoin("inc", sdk.ZeroInt()),
|
||||
sdk.NewCoin("inc", sdk.ZeroInt()),
|
||||
),
|
||||
},
|
||||
}
|
||||
return app.GenesisState{bep3.ModuleName: bep3.ModuleCdc.MustMarshalJSON(bep3Genesis)}
|
||||
}
|
||||
@ -95,5 +112,5 @@ func assetSupplies(count int) types.AssetSupplies {
|
||||
}
|
||||
|
||||
func assetSupply(denom string) types.AssetSupply {
|
||||
return types.NewAssetSupply(denom, c(denom, 0), c(denom, 0), c(denom, 0), c(denom, 10000))
|
||||
return types.NewAssetSupply(c(denom, 0), c(denom, 0), c(denom, 0))
|
||||
}
|
||||
|
@ -182,35 +182,31 @@ func (k Keeper) IterateAtomicSwapsLongtermStorage(ctx sdk.Context, inclusiveCuto
|
||||
// ------------------------------------------
|
||||
|
||||
// GetAssetSupply gets an asset's current supply from the store.
|
||||
func (k Keeper) GetAssetSupply(ctx sdk.Context, denom []byte) (types.AssetSupply, bool) {
|
||||
var supply types.AssetSupply
|
||||
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.AssetSupplyKeyPrefix)
|
||||
bz := store.Get(denom)
|
||||
func (k Keeper) GetAssetSupply(ctx sdk.Context, denom string) (types.AssetSupply, bool) {
|
||||
var assetSupply types.AssetSupply
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.AssetSupplyPrefix)
|
||||
bz := store.Get([]byte(denom))
|
||||
if bz == nil {
|
||||
return types.AssetSupply{}, false
|
||||
}
|
||||
|
||||
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &supply)
|
||||
return supply, true
|
||||
k.cdc.MustUnmarshalBinaryBare(bz, &assetSupply)
|
||||
return assetSupply, true
|
||||
}
|
||||
|
||||
// SetAssetSupply updates an asset's current active supply
|
||||
func (k Keeper) SetAssetSupply(ctx sdk.Context, supply types.AssetSupply, denom []byte) {
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.AssetSupplyKeyPrefix)
|
||||
bz := k.cdc.MustMarshalBinaryLengthPrefixed(supply)
|
||||
store.Set(denom, bz)
|
||||
// SetAssetSupply updates an asset's supply
|
||||
func (k Keeper) SetAssetSupply(ctx sdk.Context, supply types.AssetSupply, denom string) {
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.AssetSupplyPrefix)
|
||||
store.Set([]byte(denom), k.cdc.MustMarshalBinaryBare(supply))
|
||||
}
|
||||
|
||||
// IterateAssetSupplies provides an iterator over current asset supplies.
|
||||
// For each asset supply, cb will be called. If cb returns true, the iterator will close and stop.
|
||||
// IterateAssetSupplies provides an iterator over all stored AssetSupplies.
|
||||
func (k Keeper) IterateAssetSupplies(ctx sdk.Context, cb func(supply types.AssetSupply) (stop bool)) {
|
||||
iterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.key), types.AssetSupplyKeyPrefix)
|
||||
iterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.key), types.AssetSupplyPrefix)
|
||||
|
||||
defer iterator.Close()
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
var supply types.AssetSupply
|
||||
k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &supply)
|
||||
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &supply)
|
||||
|
||||
if cb(supply) {
|
||||
break
|
||||
@ -218,7 +214,7 @@ func (k Keeper) IterateAssetSupplies(ctx sdk.Context, cb func(supply types.Asset
|
||||
}
|
||||
}
|
||||
|
||||
// GetAllAssetSupplies returns current asset supplies from the store as an array of sdk.Coin
|
||||
// GetAllAssetSupplies returns all asset supplies from the store
|
||||
func (k Keeper) GetAllAssetSupplies(ctx sdk.Context) (supplies types.AssetSupplies) {
|
||||
k.IterateAssetSupplies(ctx, func(supply types.AssetSupply) bool {
|
||||
supplies = append(supplies, supply)
|
||||
|
@ -308,64 +308,32 @@ func (suite *KeeperTestSuite) TestIterateAtomicSwapsLongtermStorage() {
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGetSetAssetSupply() {
|
||||
suite.ResetChain()
|
||||
|
||||
denom := "bnb"
|
||||
// Put asset supply in store
|
||||
assetSupply := types.NewAssetSupply(denom, c(denom, 0), c(denom, 0), c(denom, 50000), c(denom, 100000))
|
||||
suite.keeper.SetAssetSupply(suite.ctx, assetSupply, []byte(denom))
|
||||
assetSupply := types.NewAssetSupply(c(denom, 0), c(denom, 0), c(denom, 50000))
|
||||
suite.keeper.SetAssetSupply(suite.ctx, assetSupply, denom)
|
||||
|
||||
// Check asset in store
|
||||
storedAssetSupply, found := suite.keeper.GetAssetSupply(suite.ctx, []byte(denom))
|
||||
storedAssetSupply, found := suite.keeper.GetAssetSupply(suite.ctx, denom)
|
||||
suite.True(found)
|
||||
suite.Equal(assetSupply, storedAssetSupply)
|
||||
|
||||
// Check fake asset supply not in store
|
||||
fakeDenom := "xyz"
|
||||
_, found = suite.keeper.GetAssetSupply(suite.ctx, []byte(fakeDenom))
|
||||
_, found = suite.keeper.GetAssetSupply(suite.ctx, fakeDenom)
|
||||
suite.False(found)
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestIterateAssetSupplies() {
|
||||
suite.ResetChain()
|
||||
|
||||
// Set asset supplies
|
||||
supplies := assetSupplies(5)
|
||||
for _, supply := range supplies {
|
||||
suite.keeper.SetAssetSupply(suite.ctx, supply, []byte(supply.Denom))
|
||||
}
|
||||
|
||||
// Read each asset supply from the store
|
||||
var readSupplies types.AssetSupplies
|
||||
suite.keeper.IterateAssetSupplies(suite.ctx, func(a types.AssetSupply) bool {
|
||||
readSupplies = append(readSupplies, a)
|
||||
return false
|
||||
})
|
||||
|
||||
// Check expected values
|
||||
for i := 0; i < len(supplies); i++ {
|
||||
suite.Contains(readSupplies, supplies[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGetAllAssetSupplies() {
|
||||
suite.ResetChain()
|
||||
|
||||
// Set asset supplies
|
||||
count := 3
|
||||
supplies := assetSupplies(count)
|
||||
for _, supply := range supplies {
|
||||
suite.keeper.SetAssetSupply(suite.ctx, supply, []byte(supply.Denom))
|
||||
}
|
||||
// Put asset supply in store
|
||||
assetSupply := types.NewAssetSupply(c("bnb", 0), c("bnb", 0), c("bnb", 50000))
|
||||
suite.keeper.SetAssetSupply(suite.ctx, assetSupply, "bnb")
|
||||
assetSupply = types.NewAssetSupply(c("inc", 0), c("inc", 0), c("inc", 50000))
|
||||
suite.keeper.SetAssetSupply(suite.ctx, assetSupply, "inc")
|
||||
|
||||
// Get all asset supplies
|
||||
readSupplies := suite.keeper.GetAllAssetSupplies(suite.ctx)
|
||||
suite.Equal(count, len(readSupplies))
|
||||
|
||||
// Check expected values
|
||||
for i := 0; i < count; i++ {
|
||||
suite.Contains(readSupplies, supplies[i])
|
||||
}
|
||||
supplies := suite.keeper.GetAllAssetSupplies(suite.ctx)
|
||||
suite.Equal(2, len(supplies))
|
||||
}
|
||||
|
||||
func TestKeeperTestSuite(t *testing.T) {
|
||||
|
@ -18,63 +18,100 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
|
||||
k.paramSubspace.SetParamSet(ctx, ¶ms)
|
||||
}
|
||||
|
||||
// GetBnbDeputyAddress returns the Bnbchain's deputy address
|
||||
func (k Keeper) GetBnbDeputyAddress(ctx sdk.Context) sdk.AccAddress {
|
||||
// ------------------------------------------
|
||||
// Asset
|
||||
// ------------------------------------------
|
||||
|
||||
// GetAsset returns the asset param associated with the input denom
|
||||
func (k Keeper) GetAsset(ctx sdk.Context, denom string) (types.AssetParam, error) {
|
||||
params := k.GetParams(ctx)
|
||||
return params.BnbDeputyAddress
|
||||
for _, asset := range params.AssetParams {
|
||||
if denom == asset.Denom {
|
||||
return asset, nil
|
||||
}
|
||||
}
|
||||
return types.AssetParam{}, sdkerrors.Wrap(types.ErrAssetNotSupported, denom)
|
||||
}
|
||||
|
||||
// GetBnbDeputyFixedFee returns the deputy's fixed fee
|
||||
func (k Keeper) GetBnbDeputyFixedFee(ctx sdk.Context) sdk.Int {
|
||||
// SetAsset sets an asset in the params
|
||||
func (k Keeper) SetAsset(ctx sdk.Context, asset types.AssetParam) {
|
||||
params := k.GetParams(ctx)
|
||||
return params.BnbDeputyFixedFee
|
||||
}
|
||||
|
||||
// GetMinAmount returns the minimum amount
|
||||
func (k Keeper) GetMinAmount(ctx sdk.Context) sdk.Int {
|
||||
params := k.GetParams(ctx)
|
||||
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
|
||||
func (k Keeper) GetMinBlockLock(ctx sdk.Context) uint64 {
|
||||
params := k.GetParams(ctx)
|
||||
return params.MinBlockLock
|
||||
}
|
||||
|
||||
// GetMaxBlockLock returns the maximum block lock
|
||||
func (k Keeper) GetMaxBlockLock(ctx sdk.Context) uint64 {
|
||||
params := k.GetParams(ctx)
|
||||
return params.MaxBlockLock
|
||||
for i := range params.AssetParams {
|
||||
if params.AssetParams[i].Denom == asset.Denom {
|
||||
params.AssetParams[i] = asset
|
||||
}
|
||||
}
|
||||
k.SetParams(ctx, params)
|
||||
}
|
||||
|
||||
// GetAssets returns a list containing all supported assets
|
||||
func (k Keeper) GetAssets(ctx sdk.Context) (types.AssetParams, bool) {
|
||||
params := k.GetParams(ctx)
|
||||
return params.SupportedAssets, len(params.SupportedAssets) > 0
|
||||
return params.AssetParams, len(params.AssetParams) > 0
|
||||
}
|
||||
|
||||
// GetAssetByDenom returns an asset by its denom
|
||||
func (k Keeper) GetAssetByDenom(ctx sdk.Context, denom string) (types.AssetParam, bool) {
|
||||
params := k.GetParams(ctx)
|
||||
for _, asset := range params.SupportedAssets {
|
||||
if asset.Denom == denom {
|
||||
return asset, true
|
||||
}
|
||||
// ------------------------------------------
|
||||
// Asset-specific getters
|
||||
// ------------------------------------------
|
||||
|
||||
// GetDeputyAddress returns the deputy address for the input denom
|
||||
func (k Keeper) GetDeputyAddress(ctx sdk.Context, denom string) (sdk.AccAddress, error) {
|
||||
asset, err := k.GetAsset(ctx, denom)
|
||||
if err != nil {
|
||||
return sdk.AccAddress{}, err
|
||||
}
|
||||
return types.AssetParam{}, false
|
||||
return asset.DeputyAddress, nil
|
||||
}
|
||||
|
||||
// GetFixedFee returns the fixed fee for incoming swaps
|
||||
func (k Keeper) GetFixedFee(ctx sdk.Context, denom string) (sdk.Int, error) {
|
||||
asset, err := k.GetAsset(ctx, denom)
|
||||
if err != nil {
|
||||
return sdk.Int{}, err
|
||||
}
|
||||
return asset.FixedFee, nil
|
||||
}
|
||||
|
||||
// GetMinSwapAmount returns the minimum swap amount
|
||||
func (k Keeper) GetMinSwapAmount(ctx sdk.Context, denom string) (sdk.Int, error) {
|
||||
asset, err := k.GetAsset(ctx, denom)
|
||||
if err != nil {
|
||||
return sdk.Int{}, err
|
||||
}
|
||||
return asset.MinSwapAmount, nil
|
||||
}
|
||||
|
||||
// GetMaxSwapAmount returns the maximum swap amount
|
||||
func (k Keeper) GetMaxSwapAmount(ctx sdk.Context, denom string) (sdk.Int, error) {
|
||||
asset, err := k.GetAsset(ctx, denom)
|
||||
if err != nil {
|
||||
return sdk.Int{}, err
|
||||
}
|
||||
return asset.MaxSwapAmount, nil
|
||||
}
|
||||
|
||||
// GetMinBlockLock returns the minimum block lock
|
||||
func (k Keeper) GetMinBlockLock(ctx sdk.Context, denom string) (uint64, error) {
|
||||
asset, err := k.GetAsset(ctx, denom)
|
||||
if err != nil {
|
||||
return uint64(0), err
|
||||
}
|
||||
return asset.MinBlockLock, nil
|
||||
}
|
||||
|
||||
// GetMaxBlockLock returns the maximum block lock
|
||||
func (k Keeper) GetMaxBlockLock(ctx sdk.Context, denom string) (uint64, error) {
|
||||
asset, err := k.GetAsset(ctx, denom)
|
||||
if err != nil {
|
||||
return uint64(0), err
|
||||
}
|
||||
return asset.MaxBlockLock, nil
|
||||
}
|
||||
|
||||
// GetAssetByCoinID returns an asset by its denom
|
||||
func (k Keeper) GetAssetByCoinID(ctx sdk.Context, coinID int) (types.AssetParam, bool) {
|
||||
params := k.GetParams(ctx)
|
||||
for _, asset := range params.SupportedAssets {
|
||||
for _, asset := range params.AssetParams {
|
||||
if asset.CoinID == coinID {
|
||||
return asset, true
|
||||
}
|
||||
@ -84,12 +121,21 @@ func (k Keeper) GetAssetByCoinID(ctx sdk.Context, coinID int) (types.AssetParam,
|
||||
|
||||
// ValidateLiveAsset checks if an asset is both supported and active
|
||||
func (k Keeper) ValidateLiveAsset(ctx sdk.Context, coin sdk.Coin) error {
|
||||
asset, found := k.GetAssetByDenom(ctx, coin.Denom)
|
||||
if !found {
|
||||
return sdkerrors.Wrap(types.ErrAssetNotSupported, coin.Denom)
|
||||
asset, err := k.GetAsset(ctx, coin.Denom)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !asset.Active {
|
||||
return sdkerrors.Wrap(types.ErrAssetNotActive, asset.Denom)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSupplyLimit returns the supply limit for the input denom
|
||||
func (k Keeper) GetSupplyLimit(ctx sdk.Context, denom string) (sdk.Int, error) {
|
||||
asset, err := k.GetAsset(ctx, denom)
|
||||
if err != nil {
|
||||
return sdk.Int{}, err
|
||||
}
|
||||
return asset.SupplyLimit, nil
|
||||
}
|
||||
|
@ -35,78 +35,81 @@ func (suite *ParamsTestSuite) SetupTest() {
|
||||
suite.addrs = addrs
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) TestGetSetBnbDeputyAddress() {
|
||||
params := suite.keeper.GetParams(suite.ctx)
|
||||
params.BnbDeputyAddress = suite.addrs[1]
|
||||
suite.NotPanics(func() { suite.keeper.SetParams(suite.ctx, params) })
|
||||
func (suite *ParamsTestSuite) TestGetSetAsset() {
|
||||
asset, err := suite.keeper.GetAsset(suite.ctx, "bnb")
|
||||
suite.Require().NoError(err)
|
||||
suite.NotPanics(func() { suite.keeper.SetAsset(suite.ctx, asset) })
|
||||
_, err = suite.keeper.GetAsset(suite.ctx, "dne")
|
||||
suite.Require().Error(err)
|
||||
|
||||
params = suite.keeper.GetParams(suite.ctx)
|
||||
suite.Equal(suite.addrs[1], params.BnbDeputyAddress)
|
||||
addr := suite.keeper.GetBnbDeputyAddress(suite.ctx)
|
||||
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) TestGetMinAmount() {
|
||||
params := suite.keeper.GetParams(suite.ctx)
|
||||
minAmount := params.MinAmount
|
||||
|
||||
res := suite.keeper.GetMinAmount(suite.ctx)
|
||||
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() {
|
||||
params := suite.keeper.GetParams(suite.ctx)
|
||||
minBlockLock := params.MinBlockLock
|
||||
|
||||
res := suite.keeper.GetMinBlockLock(suite.ctx)
|
||||
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)
|
||||
_, err = suite.keeper.GetAsset(suite.ctx, "inc")
|
||||
suite.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) TestGetAssets() {
|
||||
params := suite.keeper.GetParams(suite.ctx)
|
||||
assets := params.SupportedAssets
|
||||
|
||||
res, found := suite.keeper.GetAssets(suite.ctx)
|
||||
suite.True(found)
|
||||
suite.Equal(assets, res)
|
||||
assets, found := suite.keeper.GetAssets(suite.ctx)
|
||||
suite.Require().True(found)
|
||||
suite.Require().Equal(2, len(assets))
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) TestGetAssetByDenom() {
|
||||
params := suite.keeper.GetParams(suite.ctx)
|
||||
asset := params.SupportedAssets[0]
|
||||
func (suite *ParamsTestSuite) TestGetSetDeputyAddress() {
|
||||
asset, err := suite.keeper.GetAsset(suite.ctx, "bnb")
|
||||
suite.Require().NoError(err)
|
||||
asset.DeputyAddress = suite.addrs[1]
|
||||
suite.NotPanics(func() { suite.keeper.SetAsset(suite.ctx, asset) })
|
||||
|
||||
res, found := suite.keeper.GetAssetByDenom(suite.ctx, asset.Denom)
|
||||
suite.True(found)
|
||||
suite.Equal(asset, res)
|
||||
asset, err = suite.keeper.GetAsset(suite.ctx, "bnb")
|
||||
suite.Require().NoError(err)
|
||||
suite.Equal(suite.addrs[1], asset.DeputyAddress)
|
||||
addr, err := suite.keeper.GetDeputyAddress(suite.ctx, "bnb")
|
||||
suite.Require().NoError(err)
|
||||
suite.Equal(suite.addrs[1], addr)
|
||||
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) TestGetDeputyFixedFee() {
|
||||
asset, err := suite.keeper.GetAsset(suite.ctx, "bnb")
|
||||
suite.Require().NoError(err)
|
||||
bnbDeputyFixedFee := asset.FixedFee
|
||||
|
||||
res, err := suite.keeper.GetFixedFee(suite.ctx, asset.Denom)
|
||||
suite.Require().NoError(err)
|
||||
suite.Equal(bnbDeputyFixedFee, res)
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) TestGetMinMaxSwapAmount() {
|
||||
asset, err := suite.keeper.GetAsset(suite.ctx, "bnb")
|
||||
suite.Require().NoError(err)
|
||||
minAmount := asset.MinSwapAmount
|
||||
|
||||
res, err := suite.keeper.GetMinSwapAmount(suite.ctx, asset.Denom)
|
||||
suite.Require().NoError(err)
|
||||
suite.Equal(minAmount, res)
|
||||
|
||||
maxAmount := asset.MaxSwapAmount
|
||||
res, err = suite.keeper.GetMaxSwapAmount(suite.ctx, asset.Denom)
|
||||
suite.Require().NoError(err)
|
||||
suite.Equal(maxAmount, res)
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) TestGetMinMaxBlockLock() {
|
||||
asset, err := suite.keeper.GetAsset(suite.ctx, "bnb")
|
||||
suite.Require().NoError(err)
|
||||
minLock := asset.MinBlockLock
|
||||
|
||||
res, err := suite.keeper.GetMinBlockLock(suite.ctx, asset.Denom)
|
||||
suite.Require().NoError(err)
|
||||
suite.Equal(minLock, res)
|
||||
|
||||
maxLock := asset.MaxBlockLock
|
||||
res, err = suite.keeper.GetMaxBlockLock(suite.ctx, asset.Denom)
|
||||
suite.Require().NoError(err)
|
||||
suite.Equal(maxLock, res)
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) TestGetAssetByCoinID() {
|
||||
params := suite.keeper.GetParams(suite.ctx)
|
||||
asset := params.SupportedAssets[0]
|
||||
asset, err := suite.keeper.GetAsset(suite.ctx, "bnb")
|
||||
suite.Require().NoError(err)
|
||||
|
||||
res, found := suite.keeper.GetAssetByCoinID(suite.ctx, asset.CoinID)
|
||||
suite.True(found)
|
||||
|
@ -39,7 +39,7 @@ func queryAssetSupply(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
}
|
||||
|
||||
assetSupply, found := keeper.GetAssetSupply(ctx, []byte(requestParams.Denom))
|
||||
assetSupply, found := keeper.GetAssetSupply(ctx, requestParams.Denom)
|
||||
if !found {
|
||||
return nil, sdkerrors.Wrap(types.ErrAssetSupplyNotFound, string(requestParams.Denom))
|
||||
}
|
||||
|
@ -39,16 +39,16 @@ func (suite *QuerierTestSuite) SetupTest() {
|
||||
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
||||
|
||||
// Set up auth GenesisState
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(10)
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(11)
|
||||
coins := []sdk.Coins{}
|
||||
for j := 0; j < 10; j++ {
|
||||
for j := 0; j < 11; j++ {
|
||||
coins = append(coins, cs(c("bnb", 10000000000), c("ukava", 10000000000)))
|
||||
}
|
||||
authGS := app.NewAuthGenState(addrs, coins)
|
||||
|
||||
tApp.InitializeFromGenesisStates(
|
||||
authGS,
|
||||
NewBep3GenStateMulti(addrs[0]),
|
||||
NewBep3GenStateMulti(addrs[10]),
|
||||
)
|
||||
|
||||
suite.ctx = ctx
|
||||
@ -70,11 +70,11 @@ func (suite *QuerierTestSuite) SetupTest() {
|
||||
|
||||
// Create atomic swap and check err
|
||||
err := suite.keeper.CreateAtomicSwap(suite.ctx, randomNumberHash, timestamp, expireHeight,
|
||||
addrs[0], suite.addrs[i], TestSenderOtherChain, TestRecipientOtherChain, amount, true)
|
||||
addrs[10], suite.addrs[i], TestSenderOtherChain, TestRecipientOtherChain, amount, true)
|
||||
suite.Nil(err)
|
||||
|
||||
// Calculate swap ID and save
|
||||
swapID := types.CalculateSwapID(randomNumberHash, addrs[0], TestSenderOtherChain)
|
||||
swapID := types.CalculateSwapID(randomNumberHash, addrs[10], TestSenderOtherChain)
|
||||
swapIDs = append(swapIDs, swapID)
|
||||
isSwapID[hex.EncodeToString(swapID)] = true
|
||||
}
|
||||
@ -89,7 +89,7 @@ func (suite *QuerierTestSuite) TestQueryAssetSupply() {
|
||||
denom := "bnb"
|
||||
query := abci.RequestQuery{
|
||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetAssetSupply}, "/"),
|
||||
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryAssetSupply(tmbytes.HexBytes(denom))),
|
||||
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryAssetSupply(denom)),
|
||||
}
|
||||
|
||||
// Execute query and check the []byte result
|
||||
@ -101,8 +101,8 @@ func (suite *QuerierTestSuite) TestQueryAssetSupply() {
|
||||
var supply types.AssetSupply
|
||||
suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &supply))
|
||||
|
||||
expectedSupply := types.NewAssetSupply(denom, c(denom, 1000),
|
||||
c(denom, 0), c(denom, 0), c(denom, StandardSupplyLimit.Int64()))
|
||||
expectedSupply := types.NewAssetSupply(c(denom, 1000),
|
||||
c(denom, 0), c(denom, 0))
|
||||
suite.Equal(supply, expectedSupply)
|
||||
}
|
||||
|
||||
@ -179,9 +179,10 @@ func (suite *QuerierTestSuite) TestQueryParams() {
|
||||
var p types.Params
|
||||
suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &p))
|
||||
|
||||
bep3GenesisState := NewBep3GenStateMulti(suite.addrs[0])
|
||||
bep3GenesisState := NewBep3GenStateMulti(suite.addrs[10])
|
||||
gs := types.GenesisState{}
|
||||
types.ModuleCdc.UnmarshalJSON(bep3GenesisState["bep3"], &gs)
|
||||
// update asset supply to account for swaps that were created in setup
|
||||
suite.Equal(gs.Params, p)
|
||||
}
|
||||
|
||||
|
@ -31,29 +31,38 @@ func (k Keeper) CreateAtomicSwap(ctx sdk.Context, randomNumberHash []byte, times
|
||||
if len(amount) != 1 {
|
||||
return fmt.Errorf("amount must contain exactly one coin")
|
||||
}
|
||||
asset, err := k.GetAsset(ctx, amount[0].Denom)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := k.ValidateLiveAsset(ctx, amount[0])
|
||||
err = k.ValidateLiveAsset(ctx, amount[0])
|
||||
if err != nil {
|
||||
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))
|
||||
if amount[0].Amount.LT(asset.MinSwapAmount) || amount[0].Amount.GT(asset.MaxSwapAmount) {
|
||||
return sdkerrors.Wrapf(types.ErrInvalidAmount, "amount %d outside range [%s, %s]", amount[0].Amount, asset.MinSwapAmount, asset.MaxSwapAmount)
|
||||
}
|
||||
|
||||
// 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())
|
||||
return sdkerrors.Wrap(types.ErrInvalidTimestamp, fmt.Sprintf("block time: %s, timestamp: %s", ctx.BlockTime().String(), time.Unix(timestamp, 0).UTC().String()))
|
||||
}
|
||||
|
||||
var direction types.SwapDirection
|
||||
deputy := k.GetBnbDeputyAddress(ctx)
|
||||
if sender.Equals(deputy) {
|
||||
if sender.Equals(asset.DeputyAddress) {
|
||||
if recipient.Equals(asset.DeputyAddress) {
|
||||
return sdkerrors.Wrapf(types.ErrInvalidSwapAccount, "deputy cannot be both sender and receiver: %s", asset.DeputyAddress)
|
||||
}
|
||||
direction = types.Incoming
|
||||
} else {
|
||||
if !recipient.Equals(asset.DeputyAddress) {
|
||||
return sdkerrors.Wrapf(types.ErrInvalidSwapAccount, "deputy must be recipient for outgoing account: %s", recipient)
|
||||
}
|
||||
direction = types.Outgoing
|
||||
}
|
||||
|
||||
@ -69,18 +78,13 @@ 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.
|
||||
err = k.IncrementIncomingAssetSupply(ctx, amount[0])
|
||||
case types.Outgoing:
|
||||
if ctx.BlockTime().After(types.SupplyLimitUpgradeTime) {
|
||||
if !recipient.Equals(deputy) {
|
||||
return sdkerrors.Wrapf(types.ErrInvalidOutgoingAccount, "%s", recipient)
|
||||
}
|
||||
}
|
||||
|
||||
// Outoing swaps must have a height span within the accepted range
|
||||
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))
|
||||
if heightSpan < asset.MinBlockLock || heightSpan > asset.MaxBlockLock {
|
||||
return sdkerrors.Wrapf(types.ErrInvalidHeightSpan, "height span %d outside range [%d, %d]", heightSpan, asset.MinBlockLock, asset.MaxBlockLock)
|
||||
}
|
||||
// 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))) {
|
||||
if amount[0].Amount.LTE(asset.FixedFee.Add(asset.MinSwapAmount)) {
|
||||
return sdkerrors.Wrap(types.ErrInsufficientAmount, amount[0].String())
|
||||
}
|
||||
err = k.IncrementOutgoingAssetSupply(ctx, amount[0])
|
||||
|
@ -156,60 +156,6 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
|
||||
true,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"outgoing swap recipient before update",
|
||||
types.SupplyLimitUpgradeTime.Add(-time.Hour),
|
||||
args{
|
||||
randomNumberHash: suite.randomNumberHashes[12],
|
||||
timestamp: types.SupplyLimitUpgradeTime.Add(-time.Hour).Unix(),
|
||||
heightSpan: types.DefaultMinBlockLock,
|
||||
sender: suite.addrs[1],
|
||||
recipient: suite.addrs[2],
|
||||
senderOtherChain: TestUser1.String(),
|
||||
recipientOtherChain: TestUser2.String(),
|
||||
coins: cs(c(BNB_DENOM, 50000)),
|
||||
crossChain: true,
|
||||
direction: types.Outgoing,
|
||||
},
|
||||
true,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"outgoing swap recipient at update time",
|
||||
types.SupplyLimitUpgradeTime,
|
||||
args{
|
||||
randomNumberHash: suite.randomNumberHashes[13],
|
||||
timestamp: types.SupplyLimitUpgradeTime.Unix(),
|
||||
heightSpan: types.DefaultMinBlockLock,
|
||||
sender: suite.addrs[1],
|
||||
recipient: suite.addrs[2],
|
||||
senderOtherChain: TestUser1.String(),
|
||||
recipientOtherChain: TestUser2.String(),
|
||||
coins: cs(c(BNB_DENOM, 50000)),
|
||||
crossChain: true,
|
||||
direction: types.Outgoing,
|
||||
},
|
||||
true,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"outgoing swap recipient after update",
|
||||
types.SupplyLimitUpgradeTime.Add(time.Nanosecond),
|
||||
args{
|
||||
randomNumberHash: suite.randomNumberHashes[14],
|
||||
timestamp: types.SupplyLimitUpgradeTime.Add(time.Nanosecond).Unix(),
|
||||
heightSpan: types.DefaultMinBlockLock,
|
||||
sender: suite.addrs[1],
|
||||
recipient: suite.addrs[2],
|
||||
senderOtherChain: TestUser1.String(),
|
||||
recipientOtherChain: TestUser2.String(),
|
||||
coins: cs(c(BNB_DENOM, 50000)),
|
||||
crossChain: true,
|
||||
direction: types.Outgoing,
|
||||
},
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
|
||||
"outgoing swap amount not greater than fixed fee",
|
||||
@ -222,7 +168,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
|
||||
recipient: suite.addrs[2],
|
||||
senderOtherChain: TestSenderOtherChain,
|
||||
recipientOtherChain: TestRecipientOtherChain,
|
||||
coins: cs(c(BNB_DENOM, suite.keeper.GetBnbDeputyFixedFee(suite.ctx).Int64())),
|
||||
coins: cs(c(BNB_DENOM, 1000)),
|
||||
crossChain: true,
|
||||
direction: types.Outgoing,
|
||||
},
|
||||
@ -432,7 +378,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
|
||||
ak := suite.app.GetAccountKeeper()
|
||||
senderAccPre := ak.GetAccount(suite.ctx, tc.args.sender)
|
||||
senderBalancePre := senderAccPre.GetCoins().AmountOf(swapAssetDenom)
|
||||
assetSupplyPre, _ := suite.keeper.GetAssetSupply(suite.ctx, []byte(swapAssetDenom))
|
||||
assetSupplyPre, _ := suite.keeper.GetAssetSupply(suite.ctx, swapAssetDenom)
|
||||
|
||||
// Create atomic swap
|
||||
err := suite.keeper.CreateAtomicSwap(suite.ctx, tc.args.randomNumberHash, tc.args.timestamp,
|
||||
@ -442,7 +388,7 @@ func (suite *AtomicSwapTestSuite) TestCreateAtomicSwap() {
|
||||
// Load sender's account after swap creation
|
||||
senderAccPost := ak.GetAccount(suite.ctx, tc.args.sender)
|
||||
senderBalancePost := senderAccPost.GetCoins().AmountOf(swapAssetDenom)
|
||||
assetSupplyPost, _ := suite.keeper.GetAssetSupply(suite.ctx, []byte(swapAssetDenom))
|
||||
assetSupplyPost, _ := suite.keeper.GetAssetSupply(suite.ctx, swapAssetDenom)
|
||||
|
||||
// Load expected swap ID
|
||||
expectedSwapID := types.CalculateSwapID(tc.args.randomNumberHash, tc.args.sender, tc.args.senderOtherChain)
|
||||
@ -625,7 +571,7 @@ func (suite *AtomicSwapTestSuite) TestClaimAtomicSwap() {
|
||||
expectedRecipientAccPre := ak.GetAccount(tc.claimCtx, expectedRecipient)
|
||||
expectedRecipientBalancePre := expectedRecipientAccPre.GetCoins().AmountOf(expectedClaimAmount[0].Denom)
|
||||
// Load asset supplies prior to claim attempt
|
||||
assetSupplyPre, _ := suite.keeper.GetAssetSupply(tc.claimCtx, []byte(expectedClaimAmount[0].Denom))
|
||||
assetSupplyPre, _ := suite.keeper.GetAssetSupply(tc.claimCtx, expectedClaimAmount[0].Denom)
|
||||
|
||||
// Attempt to claim atomic swap
|
||||
err = suite.keeper.ClaimAtomicSwap(tc.claimCtx, expectedRecipient, claimSwapID, claimRandomNumber)
|
||||
@ -634,7 +580,7 @@ func (suite *AtomicSwapTestSuite) TestClaimAtomicSwap() {
|
||||
expectedRecipientAccPost := ak.GetAccount(tc.claimCtx, expectedRecipient)
|
||||
expectedRecipientBalancePost := expectedRecipientAccPost.GetCoins().AmountOf(expectedClaimAmount[0].Denom)
|
||||
// Load asset supplies after the claim attempt
|
||||
assetSupplyPost, _ := suite.keeper.GetAssetSupply(tc.claimCtx, []byte(expectedClaimAmount[0].Denom))
|
||||
assetSupplyPost, _ := suite.keeper.GetAssetSupply(tc.claimCtx, expectedClaimAmount[0].Denom)
|
||||
|
||||
if tc.expectPass {
|
||||
suite.NoError(err)
|
||||
@ -773,7 +719,7 @@ func (suite *AtomicSwapTestSuite) TestRefundAtomicSwap() {
|
||||
originalSenderAccPre := ak.GetAccount(tc.refundCtx, sender)
|
||||
originalSenderBalancePre := originalSenderAccPre.GetCoins().AmountOf(expectedRefundAmount[0].Denom)
|
||||
// Load asset supply prior to swap refund
|
||||
assetSupplyPre, _ := suite.keeper.GetAssetSupply(tc.refundCtx, []byte(expectedRefundAmount[0].Denom))
|
||||
assetSupplyPre, _ := suite.keeper.GetAssetSupply(tc.refundCtx, expectedRefundAmount[0].Denom)
|
||||
|
||||
// Attempt to refund atomic swap
|
||||
err = suite.keeper.RefundAtomicSwap(tc.refundCtx, sender, refundSwapID)
|
||||
@ -782,7 +728,7 @@ func (suite *AtomicSwapTestSuite) TestRefundAtomicSwap() {
|
||||
originalSenderAccPost := ak.GetAccount(tc.refundCtx, sender)
|
||||
originalSenderBalancePost := originalSenderAccPost.GetCoins().AmountOf(expectedRefundAmount[0].Denom)
|
||||
// Load asset supply after to swap refund
|
||||
assetSupplyPost, _ := suite.keeper.GetAssetSupply(tc.refundCtx, []byte(expectedRefundAmount[0].Denom))
|
||||
assetSupplyPost, _ := suite.keeper.GetAssetSupply(tc.refundCtx, expectedRefundAmount[0].Denom)
|
||||
|
||||
if tc.expectPass {
|
||||
suite.NoError(err)
|
||||
|
81
x/bep3/legacy/v0_11/types.go
Normal file
81
x/bep3/legacy/v0_11/types.go
Normal file
@ -0,0 +1,81 @@
|
||||
package v0_11
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||
)
|
||||
|
||||
// GenesisState - all bep3 state that must be provided at genesis
|
||||
type GenesisState struct {
|
||||
Params Params `json:"params" yaml:"params"`
|
||||
AtomicSwaps AtomicSwaps `json:"atomic_swaps" yaml:"atomic_swaps"`
|
||||
}
|
||||
|
||||
// Params governance parameters for the bep3 module
|
||||
type Params struct {
|
||||
AssetParams AssetParams `json:"asset_params" yaml:"asset_params"`
|
||||
}
|
||||
|
||||
// AssetParam parameters that must be specified for each bep3 asset
|
||||
type AssetParam struct {
|
||||
Denom string `json:"denom" yaml:"denom"` // name of the asset
|
||||
CoinID int `json:"coin_id" yaml:"coin_id"` // SLIP-0044 registered coin type - see https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
||||
SupplyLimit AssetSupply `json:"supply_limit" yaml:"supply_limit"` // asset supply limit
|
||||
Active bool `json:"active" yaml:"active"` // denotes if asset is available or paused
|
||||
DeputyAddress sdk.AccAddress `json:"deputy_address" yaml:"deputy_address"` // the address of the relayer process
|
||||
FixedFee sdk.Int `json:"incoming_swap_fixed_fee" yaml:"incoming_swap_fixed_fee"` // the fixed fee charged by the relayer process for incoming swaps
|
||||
MinSwapAmount sdk.Int `json:"min_swap_amount" yaml:"min_swap_amount"` // Minimum swap amount
|
||||
MaxSwapAmount sdk.Int `json:"max_swap_amount" yaml:"max_swap_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
|
||||
}
|
||||
|
||||
// AssetParams array of AssetParam
|
||||
type AssetParams []AssetParam
|
||||
|
||||
// AssetSupply contains information about an asset's supply
|
||||
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"`
|
||||
SupplyLimit sdk.Coin `json:"supply_limit" yaml:"supply_limit"`
|
||||
}
|
||||
|
||||
// AtomicSwap contains the information for an atomic swap
|
||||
type AtomicSwap struct {
|
||||
Amount sdk.Coins `json:"amount" yaml:"amount"`
|
||||
RandomNumberHash tmbytes.HexBytes `json:"random_number_hash" yaml:"random_number_hash"`
|
||||
ExpireHeight uint64 `json:"expire_height" yaml:"expire_height"`
|
||||
Timestamp int64 `json:"timestamp" yaml:"timestamp"`
|
||||
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||
Recipient sdk.AccAddress `json:"recipient" yaml:"recipient"`
|
||||
SenderOtherChain string `json:"sender_other_chain" yaml:"sender_other_chain"`
|
||||
RecipientOtherChain string `json:"recipient_other_chain" yaml:"recipient_other_chain"`
|
||||
ClosedBlock int64 `json:"closed_block" yaml:"closed_block"`
|
||||
Status SwapStatus `json:"status" yaml:"status"`
|
||||
CrossChain bool `json:"cross_chain" yaml:"cross_chain"`
|
||||
Direction SwapDirection `json:"direction" yaml:"direction"`
|
||||
}
|
||||
|
||||
// AtomicSwaps is a slice of AtomicSwap
|
||||
type AtomicSwaps []AtomicSwap
|
||||
|
||||
// SwapStatus is the status of an AtomicSwap
|
||||
type SwapStatus byte
|
||||
|
||||
// swap statuses
|
||||
const (
|
||||
NULL SwapStatus = 0x00
|
||||
Open SwapStatus = 0x01
|
||||
Completed SwapStatus = 0x02
|
||||
Expired SwapStatus = 0x03
|
||||
)
|
||||
|
||||
// SwapDirection is the direction of an AtomicSwap
|
||||
type SwapDirection byte
|
||||
|
||||
const (
|
||||
INVALID SwapDirection = 0x00
|
||||
Incoming SwapDirection = 0x01
|
||||
Outgoing SwapDirection = 0x02
|
||||
)
|
151
x/bep3/legacy/v0_9/types.go
Normal file
151
x/bep3/legacy/v0_9/types.go
Normal file
@ -0,0 +1,151 @@
|
||||
package v0_9
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||
)
|
||||
|
||||
const (
|
||||
ModuleName = "bep3"
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultBnbDeputyFixedFee sdk.Int = sdk.NewInt(1000) // 0.00001 BNB
|
||||
DefaultMinAmount sdk.Int = sdk.ZeroInt()
|
||||
DefaultMaxAmount sdk.Int = sdk.NewInt(1000000000000) // 10,000 BNB
|
||||
DefaultMinBlockLock uint64 = 220
|
||||
DefaultMaxBlockLock uint64 = 270
|
||||
DefaultSupportedAssets = AssetParams{
|
||||
AssetParam{
|
||||
Denom: "bnb",
|
||||
CoinID: 714,
|
||||
Limit: sdk.NewInt(350000000000000), // 3,500,000 BNB
|
||||
Active: true,
|
||||
},
|
||||
}
|
||||
KeySupportedAssets = []byte("SupportedAssets")
|
||||
)
|
||||
|
||||
// Params v0.9 governance parameters for bep3 module
|
||||
type Params struct {
|
||||
BnbDeputyAddress sdk.AccAddress `json:"bnb_deputy_address" yaml:"bnb_deputy_address"` // Bnbchain deputy address
|
||||
BnbDeputyFixedFee sdk.Int `json:"bnb_deputy_fixed_fee" yaml:"bnb_deputy_fixed_fee"` // Deputy fixed fee in BNB
|
||||
MinAmount sdk.Int `json:"min_amount" yaml:"min_amount"` // Minimum swap amount
|
||||
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
|
||||
}
|
||||
|
||||
// NewParams returns a new params object
|
||||
func NewParams(bnbDeputyAddress sdk.AccAddress, bnbDeputyFixedFee, minAmount,
|
||||
maxAmount sdk.Int, minBlockLock, maxBlockLock uint64, supportedAssets AssetParams,
|
||||
) Params {
|
||||
return Params{
|
||||
BnbDeputyAddress: bnbDeputyAddress,
|
||||
BnbDeputyFixedFee: bnbDeputyFixedFee,
|
||||
MinAmount: minAmount,
|
||||
MaxAmount: maxAmount,
|
||||
MinBlockLock: minBlockLock,
|
||||
MaxBlockLock: maxBlockLock,
|
||||
SupportedAssets: supportedAssets,
|
||||
}
|
||||
}
|
||||
|
||||
// AssetParam v0.9 governance parameters for each asset supported on kava chain
|
||||
type AssetParam struct {
|
||||
Denom string `json:"denom" yaml:"denom"` // name of the asset
|
||||
CoinID int `json:"coin_id" yaml:"coin_id"` // internationally recognized coin ID
|
||||
Limit sdk.Int `json:"limit" yaml:"limit"` // asset supply limit
|
||||
Active bool `json:"active" yaml:"active"` // denotes if asset is available or paused
|
||||
}
|
||||
|
||||
// AssetParams is a slice of AssetParams
|
||||
type AssetParams []AssetParam
|
||||
|
||||
// GenesisState - all bep3 state that must be provided at genesis
|
||||
type GenesisState struct {
|
||||
Params Params `json:"params" yaml:"params"`
|
||||
AtomicSwaps AtomicSwaps `json:"atomic_swaps" yaml:"atomic_swaps"`
|
||||
AssetSupplies AssetSupplies `json:"assets_supplies" yaml:"assets_supplies"`
|
||||
}
|
||||
|
||||
// NewGenesisState creates a new GenesisState object
|
||||
func NewGenesisState(params Params, swaps AtomicSwaps, supplies AssetSupplies) GenesisState {
|
||||
return GenesisState{
|
||||
Params: params,
|
||||
AtomicSwaps: swaps,
|
||||
AssetSupplies: supplies,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultGenesisState - default GenesisState used by Cosmos Hub
|
||||
func DefaultGenesisState() GenesisState {
|
||||
return NewGenesisState(
|
||||
DefaultParams(),
|
||||
AtomicSwaps{},
|
||||
AssetSupplies{},
|
||||
)
|
||||
}
|
||||
|
||||
// DefaultParams returns default params for bep3 module
|
||||
func DefaultParams() Params {
|
||||
defaultBnbDeputyAddress, err := sdk.AccAddressFromBech32("kava1r4v2zdhdalfj2ydazallqvrus9fkphmglhn6u6")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return NewParams(defaultBnbDeputyAddress, DefaultBnbDeputyFixedFee, DefaultMinAmount,
|
||||
DefaultMaxAmount, DefaultMinBlockLock, DefaultMaxBlockLock, DefaultSupportedAssets)
|
||||
}
|
||||
|
||||
// AtomicSwap contains the information for an atomic swap
|
||||
type AtomicSwap struct {
|
||||
Amount sdk.Coins `json:"amount" yaml:"amount"`
|
||||
RandomNumberHash tmbytes.HexBytes `json:"random_number_hash" yaml:"random_number_hash"`
|
||||
ExpireHeight uint64 `json:"expire_height" yaml:"expire_height"`
|
||||
Timestamp int64 `json:"timestamp" yaml:"timestamp"`
|
||||
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||
Recipient sdk.AccAddress `json:"recipient" yaml:"recipient"`
|
||||
SenderOtherChain string `json:"sender_other_chain" yaml:"sender_other_chain"`
|
||||
RecipientOtherChain string `json:"recipient_other_chain" yaml:"recipient_other_chain"`
|
||||
ClosedBlock int64 `json:"closed_block" yaml:"closed_block"`
|
||||
Status SwapStatus `json:"status" yaml:"status"`
|
||||
CrossChain bool `json:"cross_chain" yaml:"cross_chain"`
|
||||
Direction SwapDirection `json:"direction" yaml:"direction"`
|
||||
}
|
||||
|
||||
// AtomicSwaps is a slice of AtomicSwap
|
||||
type AtomicSwaps []AtomicSwap
|
||||
|
||||
// AssetSupply contains information about an asset's supply
|
||||
type AssetSupply struct {
|
||||
Denom string `json:"denom" yaml:"denom"`
|
||||
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"`
|
||||
SupplyLimit sdk.Coin `json:"supply_limit" yaml:"supply_limit"`
|
||||
}
|
||||
|
||||
// AssetSupplies is a slice of AssetSupply
|
||||
type AssetSupplies []AssetSupply
|
||||
|
||||
// SwapStatus is the status of an AtomicSwap
|
||||
type SwapStatus byte
|
||||
|
||||
// swap statuses
|
||||
const (
|
||||
NULL SwapStatus = 0x00
|
||||
Open SwapStatus = 0x01
|
||||
Completed SwapStatus = 0x02
|
||||
Expired SwapStatus = 0x03
|
||||
)
|
||||
|
||||
// SwapDirection is the direction of an AtomicSwap
|
||||
type SwapDirection byte
|
||||
|
||||
const (
|
||||
INVALID SwapDirection = 0x00
|
||||
Incoming SwapDirection = 0x01
|
||||
Outgoing SwapDirection = 0x02
|
||||
)
|
@ -21,17 +21,16 @@ func DecodeStore(cdc *codec.Codec, kvA, kvB kv.Pair) string {
|
||||
cdc.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &swapB)
|
||||
return fmt.Sprintf("%v\n%v", swapA, swapB)
|
||||
|
||||
case bytes.Equal(kvA.Key[:1], types.AssetSupplyKeyPrefix):
|
||||
var supplyA, supplyB types.AssetSupply
|
||||
cdc.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &supplyA)
|
||||
cdc.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &supplyB)
|
||||
return fmt.Sprintf("%s\n%s", supplyA, supplyB)
|
||||
|
||||
case bytes.Equal(kvA.Key[:1], types.AtomicSwapByBlockPrefix),
|
||||
bytes.Equal(kvA.Key[:1], types.AtomicSwapLongtermStoragePrefix):
|
||||
var bytesA tmbytes.HexBytes = kvA.Value
|
||||
var bytesB tmbytes.HexBytes = kvA.Value
|
||||
return fmt.Sprintf("%s\n%s", bytesA.String(), bytesB.String())
|
||||
case bytes.Equal(kvA.Key[:1], types.AssetSupplyPrefix):
|
||||
var supplyA, supplyB types.AssetSupply
|
||||
cdc.MustUnmarshalBinaryLengthPrefixed(kvA.Value, &supplyA)
|
||||
cdc.MustUnmarshalBinaryLengthPrefixed(kvB.Value, &supplyB)
|
||||
return fmt.Sprintf("%s\n%s", supplyA, supplyB)
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid %s key prefix %X", types.ModuleName, kvA.Key[:1]))
|
||||
|
@ -27,12 +27,12 @@ func TestDecodeDistributionStore(t *testing.T) {
|
||||
|
||||
oneCoin := sdk.NewCoin("coin", sdk.OneInt())
|
||||
swap := types.NewAtomicSwap(sdk.Coins{oneCoin}, nil, 10, 100, nil, nil, "otherChainSender", "otherChainRec", 200, types.Completed, true, types.Outgoing)
|
||||
supply := types.AssetSupply{Denom: "coin", IncomingSupply: oneCoin, OutgoingSupply: oneCoin, CurrentSupply: oneCoin, SupplyLimit: oneCoin}
|
||||
supply := types.AssetSupply{IncomingSupply: oneCoin, OutgoingSupply: oneCoin, CurrentSupply: oneCoin}
|
||||
bz := tmbytes.HexBytes([]byte{1, 2})
|
||||
|
||||
kvPairs := kv.Pairs{
|
||||
kv.Pair{Key: types.AtomicSwapKeyPrefix, Value: cdc.MustMarshalBinaryLengthPrefixed(swap)},
|
||||
kv.Pair{Key: types.AssetSupplyKeyPrefix, Value: cdc.MustMarshalBinaryLengthPrefixed(supply)},
|
||||
kv.Pair{Key: types.AssetSupplyPrefix, Value: cdc.MustMarshalBinaryLengthPrefixed(supply)},
|
||||
kv.Pair{Key: types.AtomicSwapByBlockPrefix, Value: bz},
|
||||
kv.Pair{Key: types.AtomicSwapByBlockPrefix, Value: bz},
|
||||
kv.Pair{Key: []byte{0x99}, Value: []byte{0x99}},
|
||||
|
@ -16,21 +16,13 @@ import (
|
||||
"github.com/kava-labs/kava/x/bep3/types"
|
||||
)
|
||||
|
||||
// Simulation parameter constants
|
||||
const (
|
||||
BnbDeputyAddress = "bnb_deputy_address"
|
||||
BnbDeputyFixedFee = "bnb_deputy_fixed_fee"
|
||||
MinAmount = "min_amount"
|
||||
MaxAmount = "max_amount"
|
||||
MinBlockLock = "min_block_lock"
|
||||
MaxBlockLock = "max_block_lock"
|
||||
SupportedAssets = "supported_assets"
|
||||
)
|
||||
|
||||
var (
|
||||
MaxSupplyLimit = sdk.NewInt(1000000000000)
|
||||
accs []simulation.Account
|
||||
ConsistentDenoms = [3]string{"bnb", "xrp", "btc"}
|
||||
MaxSupplyLimit = 1000000000000
|
||||
MinSupplyLimit = 100000000
|
||||
MinSwapAmountLimit = 999
|
||||
accs []simulation.Account
|
||||
ConsistentDenoms = [3]string{"bnb", "xrp", "btc"}
|
||||
MinBlockLock = uint64(5)
|
||||
)
|
||||
|
||||
// GenRandBnbDeputy randomized BnbDeputyAddress
|
||||
@ -39,39 +31,48 @@ func GenRandBnbDeputy(r *rand.Rand) simulation.Account {
|
||||
return acc
|
||||
}
|
||||
|
||||
// GenRandBnbDeputyFixedFee randomized BnbDeputyFixedFee in range [2, 10000]
|
||||
func GenRandBnbDeputyFixedFee(r *rand.Rand) sdk.Int {
|
||||
// GenRandFixedFee randomized FixedFee in range [1, 10000]
|
||||
func GenRandFixedFee(r *rand.Rand) sdk.Int {
|
||||
min := int(1)
|
||||
max := types.DefaultBnbDeputyFixedFee.Int64()
|
||||
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()
|
||||
// GenMinSwapAmount randomized MinAmount in range [1, 1000]
|
||||
func GenMinSwapAmount(r *rand.Rand) sdk.Int {
|
||||
return sdk.OneInt().Add(simulation.RandomAmount(r, sdk.NewInt(int64(MinSwapAmountLimit))))
|
||||
}
|
||||
|
||||
// GenMaxSwapAmount randomized MaxAmount
|
||||
func GenMaxSwapAmount(r *rand.Rand, minAmount sdk.Int, supplyMax sdk.Int) sdk.Int {
|
||||
min := minAmount.Int64()
|
||||
max := supplyMax.Quo(sdk.NewInt(100)).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))
|
||||
// GenSupplyLimit generates a random SupplyLimit
|
||||
func GenSupplyLimit(r *rand.Rand, max int) sdk.Int {
|
||||
max = simulation.RandIntBetween(r, MinSupplyLimit, max)
|
||||
return sdk.NewInt(int64(max))
|
||||
}
|
||||
|
||||
// GenSupplyLimit generates a random SupplyLimit
|
||||
func GenAssetSupply(r *rand.Rand, denom string) types.AssetSupply {
|
||||
return types.NewAssetSupply(
|
||||
sdk.NewCoin(denom, sdk.ZeroInt()), sdk.NewCoin(denom, sdk.ZeroInt()),
|
||||
sdk.NewCoin(denom, sdk.ZeroInt()))
|
||||
}
|
||||
|
||||
// GenMinBlockLock randomized MinBlockLock
|
||||
func GenMinBlockLock(r *rand.Rand) uint64 {
|
||||
min := int(1)
|
||||
max := int(types.DefaultMaxBlockLock)
|
||||
return uint64(r.Intn(max-min) + min)
|
||||
return MinBlockLock
|
||||
}
|
||||
|
||||
// GenMaxBlockLock randomized MaxBlockLock
|
||||
func GenMaxBlockLock(r *rand.Rand, minBlockLock uint64) uint64 {
|
||||
min := int(minBlockLock)
|
||||
max := int(types.DefaultMaxBlockLock)
|
||||
return uint64(r.Intn(max-min) + min)
|
||||
max := int(50)
|
||||
return uint64(r.Intn(max-int(MinBlockLock)) + int(MinBlockLock+1))
|
||||
}
|
||||
|
||||
// GenSupportedAssets gets randomized SupportedAssets
|
||||
@ -92,12 +93,21 @@ func GenSupportedAssets(r *rand.Rand) types.AssetParams {
|
||||
|
||||
func genSupportedAsset(r *rand.Rand, denom string) types.AssetParam {
|
||||
coinID, _ := simulation.RandPositiveInt(r, sdk.NewInt(100000))
|
||||
limit, _ := simulation.RandPositiveInt(r, MaxSupplyLimit)
|
||||
limit := GenSupplyLimit(r, MaxSupplyLimit)
|
||||
|
||||
minSwapAmount := GenMinSwapAmount(r)
|
||||
minBlockLock := GenMinBlockLock(r)
|
||||
return types.AssetParam{
|
||||
Denom: denom,
|
||||
CoinID: int(coinID.Int64()),
|
||||
Limit: limit,
|
||||
Active: true,
|
||||
Denom: denom,
|
||||
CoinID: int(coinID.Int64()),
|
||||
SupplyLimit: limit,
|
||||
Active: true,
|
||||
DeputyAddress: GenRandBnbDeputy(r).Address,
|
||||
FixedFee: GenRandFixedFee(r),
|
||||
MinSwapAmount: minSwapAmount,
|
||||
MaxSwapAmount: GenMaxSwapAmount(r, minSwapAmount, limit),
|
||||
MinBlockLock: minBlockLock,
|
||||
MaxBlockLock: GenMaxBlockLock(r, minBlockLock),
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,31 +133,19 @@ func RandomizedGenState(simState *module.SimulationState) {
|
||||
}
|
||||
|
||||
func loadRandomBep3GenState(simState *module.SimulationState) types.GenesisState {
|
||||
bnbDeputy := GenRandBnbDeputy(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
|
||||
minBlockLock := uint64(50)
|
||||
maxBlockLock := minBlockLock * 2
|
||||
|
||||
var supportedAssets types.AssetParams
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, SupportedAssets, &supportedAssets, simState.Rand,
|
||||
func(r *rand.Rand) { supportedAssets = GenSupportedAssets(r) },
|
||||
)
|
||||
supportedAssets := GenSupportedAssets(simState.Rand)
|
||||
supplies := types.AssetSupplies{}
|
||||
for _, asset := range supportedAssets {
|
||||
supply := GenAssetSupply(simState.Rand, asset.Denom)
|
||||
supplies = append(supplies, supply)
|
||||
}
|
||||
|
||||
bep3Genesis := types.GenesisState{
|
||||
Params: types.Params{
|
||||
BnbDeputyAddress: bnbDeputy.Address,
|
||||
BnbDeputyFixedFee: bnbDeputyFixedFee,
|
||||
MinAmount: minAmount,
|
||||
MaxAmount: maxAmount,
|
||||
MinBlockLock: minBlockLock,
|
||||
MaxBlockLock: maxBlockLock,
|
||||
SupportedAssets: supportedAssets,
|
||||
AssetParams: supportedAssets,
|
||||
},
|
||||
Supplies: supplies,
|
||||
}
|
||||
|
||||
return bep3Genesis
|
||||
@ -156,22 +154,20 @@ func loadRandomBep3GenState(simState *module.SimulationState) types.GenesisState
|
||||
func loadAuthGenState(simState *module.SimulationState, bep3Genesis types.GenesisState) (auth.GenesisState, []sdk.Coins) {
|
||||
var authGenesis auth.GenesisState
|
||||
simState.Cdc.MustUnmarshalJSON(simState.GenState[auth.ModuleName], &authGenesis)
|
||||
|
||||
deputy, found := getAccount(authGenesis.Accounts, bep3Genesis.Params.BnbDeputyAddress)
|
||||
if !found {
|
||||
panic("deputy address not found in available accounts")
|
||||
}
|
||||
|
||||
// Load total limit of each supported asset to deputy's account
|
||||
var totalCoins []sdk.Coins
|
||||
for _, asset := range bep3Genesis.Params.SupportedAssets {
|
||||
assetCoin := sdk.NewCoins(sdk.NewCoin(asset.Denom, asset.Limit))
|
||||
for _, asset := range bep3Genesis.Params.AssetParams {
|
||||
deputy, found := getAccount(authGenesis.Accounts, asset.DeputyAddress)
|
||||
if !found {
|
||||
panic("deputy address not found in available accounts")
|
||||
}
|
||||
assetCoin := sdk.NewCoins(sdk.NewCoin(asset.Denom, asset.SupplyLimit))
|
||||
if err := deputy.SetCoins(deputy.GetCoins().Add(assetCoin...)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
totalCoins = append(totalCoins, assetCoin)
|
||||
authGenesis.Accounts = replaceOrAppendAccount(authGenesis.Accounts, deputy)
|
||||
}
|
||||
authGenesis.Accounts = replaceOrAppendAccount(authGenesis.Accounts, deputy)
|
||||
|
||||
return authGenesis, totalCoins
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
noOpMsg = simulation.NoOpMsg(types.ModuleName)
|
||||
noOpMsg = simulation.NoOpMsg(types.ModuleName)
|
||||
randomNumber = []byte{114, 21, 74, 180, 81, 92, 21, 91, 173, 164, 143, 111, 120, 58, 241, 58, 40, 22, 59, 133, 102, 233, 55, 149, 12, 199, 231, 63, 122, 23, 88, 9}
|
||||
)
|
||||
|
||||
@ -50,50 +50,65 @@ func SimulateMsgCreateAtomicSwap(ak types.AccountKeeper, k keeper.Keeper) simula
|
||||
return func(
|
||||
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string,
|
||||
) (simulation.OperationMsg, []simulation.FutureOperation, error) {
|
||||
|
||||
// Set up deputy address as it's required for all atomic swaps
|
||||
deputyAddr := k.GetBnbDeputyAddress(ctx)
|
||||
deputyAcc, foundDeputy := simulation.FindAccount(accs, deputyAddr)
|
||||
if !foundDeputy {
|
||||
// Get asset supplies and shuffle them
|
||||
assets, found := k.GetAssets(ctx)
|
||||
if !found {
|
||||
return noOpMsg, nil, nil
|
||||
}
|
||||
|
||||
// Get asset supplies and shuffle them
|
||||
supplies := k.GetAllAssetSupplies(ctx)
|
||||
r.Shuffle(len(supplies), func(i, j int) {
|
||||
supplies[i], supplies[j] = supplies[j], supplies[i]
|
||||
r.Shuffle(len(assets), func(i, j int) {
|
||||
assets[i], assets[j] = assets[j], assets[i]
|
||||
})
|
||||
|
||||
// Search for an account that holds coins received by an atomic swap
|
||||
minAmountPlusFee := k.GetMinAmount(ctx).Add(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)
|
||||
senderOutgoing, selectedAsset, found := findValidAccountAssetPair(accs, assets, func(simAcc simulation.Account, asset types.AssetParam) bool {
|
||||
supply, found := k.GetAssetSupply(ctx, asset.Denom)
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
if supply.CurrentSupply.Amount.IsPositive() {
|
||||
authAcc := ak.GetAccount(ctx, simAcc.Address)
|
||||
// deputy cannot be sender of outgoing swap
|
||||
if authAcc.GetAddress().Equals(asset.DeputyAddress) {
|
||||
return false
|
||||
}
|
||||
// Search for an account that holds coins received by an atomic swap
|
||||
minAmountPlusFee := asset.MinSwapAmount.Add(asset.FixedFee)
|
||||
if authAcc.SpendableCoins(ctx.BlockTime()).AmountOf(asset.Denom).GT(minAmountPlusFee) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
// Set sender, recipient, and denom depending on swap direction
|
||||
var sender simulation.Account
|
||||
var recipient simulation.Account
|
||||
var denom string
|
||||
var asset types.AssetParam
|
||||
|
||||
// If an outgoing swap can be created, it's chosen 50% of the time.
|
||||
if found && r.Intn(100) < 50 {
|
||||
sender = senderOut
|
||||
recipient = deputyAcc
|
||||
denom = asset.Denom
|
||||
} else {
|
||||
sender = deputyAcc
|
||||
recipient, _ = simulation.RandomAcc(r, accs)
|
||||
// Randomly select an asset from supported assets
|
||||
assets, foundAsset := k.GetAssets(ctx)
|
||||
if !foundAsset {
|
||||
return noOpMsg, nil, fmt.Errorf("no supported assets found")
|
||||
deputy, found := simulation.FindAccount(accs, selectedAsset.DeputyAddress)
|
||||
if !found {
|
||||
return noOpMsg, nil, nil
|
||||
}
|
||||
denom = assets[r.Intn(len(assets))].Denom
|
||||
sender = senderOutgoing
|
||||
recipient = deputy
|
||||
asset = selectedAsset
|
||||
} else {
|
||||
// if an outgoing swap cannot be created or was not selected, simulate an incoming swap
|
||||
assets, _ := k.GetAssets(ctx)
|
||||
asset = assets[r.Intn(len(assets))]
|
||||
var eligibleAccs []simulation.Account
|
||||
for _, simAcc := range accs {
|
||||
// don't allow recipient of incoming swap to be the deputy
|
||||
if simAcc.Address.Equals(asset.DeputyAddress) {
|
||||
continue
|
||||
}
|
||||
eligibleAccs = append(eligibleAccs, simAcc)
|
||||
}
|
||||
recipient, _ = simulation.RandomAcc(r, eligibleAccs)
|
||||
deputy, found := simulation.FindAccount(accs, asset.DeputyAddress)
|
||||
if !found {
|
||||
return noOpMsg, nil, nil
|
||||
}
|
||||
sender = deputy
|
||||
|
||||
}
|
||||
|
||||
recipientOtherChain := simulation.RandStringOfLength(r, 43)
|
||||
@ -111,32 +126,33 @@ func SimulateMsgCreateAtomicSwap(ak types.AccountKeeper, k keeper.Keeper) simula
|
||||
}
|
||||
|
||||
// Get maximum valid amount
|
||||
maximumAmount := senderAcc.SpendableCoins(ctx.BlockTime()).Sub(fees).AmountOf(denom)
|
||||
maximumAmount := senderAcc.SpendableCoins(ctx.BlockTime()).Sub(fees).AmountOf(asset.Denom)
|
||||
// The maximum amount for outgoing swaps is limited by the asset's current supply
|
||||
if recipient.Equals(deputyAcc) {
|
||||
assetSupply, foundAssetSupply := k.GetAssetSupply(ctx, []byte(denom))
|
||||
if recipient.Address.Equals(asset.DeputyAddress) {
|
||||
assetSupply, foundAssetSupply := k.GetAssetSupply(ctx, asset.Denom)
|
||||
if !foundAssetSupply {
|
||||
return noOpMsg, nil, fmt.Errorf("no asset supply found")
|
||||
return noOpMsg, nil, fmt.Errorf("no asset supply found for %s", asset.Denom)
|
||||
}
|
||||
if maximumAmount.GT(assetSupply.CurrentSupply.Amount) {
|
||||
maximumAmount = assetSupply.CurrentSupply.Amount
|
||||
if maximumAmount.GT(assetSupply.CurrentSupply.Amount.Sub(assetSupply.OutgoingSupply.Amount)) {
|
||||
maximumAmount = assetSupply.CurrentSupply.Amount.Sub(assetSupply.OutgoingSupply.Amount)
|
||||
}
|
||||
}
|
||||
|
||||
// The maximum amount for all swaps is limited by the total max limit
|
||||
if maximumAmount.GT(k.GetMaxAmount(ctx)) {
|
||||
maximumAmount = k.GetMaxAmount(ctx)
|
||||
if maximumAmount.GT(asset.MaxSwapAmount) {
|
||||
maximumAmount = asset.MaxSwapAmount
|
||||
}
|
||||
|
||||
// Get an amount of coins between 0.1 and 2% of total coins
|
||||
amount := maximumAmount.Quo(sdk.NewInt(int64(simulation.RandIntBetween(r, 50, 1000))))
|
||||
minAmountPlusFee := asset.MinSwapAmount.Add(asset.FixedFee)
|
||||
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)", asset.Denom), "", false, nil), nil, nil
|
||||
}
|
||||
coins := sdk.NewCoins(sdk.NewCoin(denom, amount))
|
||||
coins := sdk.NewCoins(sdk.NewCoin(asset.Denom, amount))
|
||||
|
||||
// We're assuming that sims are run with -NumBlocks=100
|
||||
heightSpan := uint64(55)
|
||||
heightSpan := uint64(simulation.RandIntBetween(r, int(asset.MinBlockLock), int(asset.MaxBlockLock)))
|
||||
|
||||
msg := types.NewMsgCreateAtomicSwap(
|
||||
sender.Address, recipient.Address, recipientOtherChain, senderOtherChain,
|
||||
@ -162,8 +178,10 @@ func SimulateMsgCreateAtomicSwap(ak types.AccountKeeper, k keeper.Keeper) simula
|
||||
var futureOp simulation.FutureOperation
|
||||
swapID := types.CalculateSwapID(msg.RandomNumberHash, msg.From, msg.SenderOtherChain)
|
||||
if r.Intn(100) < 50 {
|
||||
// Claim future operation
|
||||
executionBlock := uint64(ctx.BlockHeight()) + msg.HeightSpan/2
|
||||
// Claim future operation - choose between next block and the block before height span
|
||||
executionBlock := uint64(
|
||||
int(ctx.BlockHeight()+1) + r.Intn(int(heightSpan-1)))
|
||||
|
||||
futureOp = simulation.FutureOperation{
|
||||
BlockHeight: int(executionBlock),
|
||||
Op: operationClaimAtomicSwap(ak, k, swapID, randomNumber),
|
||||
@ -188,13 +206,51 @@ func operationClaimAtomicSwap(ak types.AccountKeeper, k keeper.Keeper, swapID []
|
||||
simAccount, _ := simulation.RandomAcc(r, accs)
|
||||
acc := ak.GetAccount(ctx, simAccount.Address)
|
||||
|
||||
msg := types.NewMsgClaimAtomicSwap(acc.GetAddress(), swapID, randomNumber)
|
||||
swap, found := k.GetAtomicSwap(ctx, swapID)
|
||||
if !found {
|
||||
return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("cannot claim: swap with ID %s not found", swapID)
|
||||
}
|
||||
// check that asset supply supports claiming (it could have changed due to a param change proposal)
|
||||
// use CacheContext so changes don't take effect
|
||||
cacheCtx, _ := ctx.CacheContext()
|
||||
switch swap.Direction {
|
||||
case types.Incoming:
|
||||
err := k.DecrementIncomingAssetSupply(cacheCtx, swap.Amount[0])
|
||||
if err != nil {
|
||||
return simulation.NewOperationMsgBasic(types.ModuleName, fmt.Sprintf("no-operation (could not claim - unable to decrement incoming asset supply %s)", swap.Amount[0].Denom), "", false, nil), nil, nil
|
||||
}
|
||||
err = k.IncrementCurrentAssetSupply(cacheCtx, swap.Amount[0])
|
||||
if err != nil {
|
||||
return simulation.NewOperationMsgBasic(types.ModuleName, fmt.Sprintf("no-operation (could not claim - unable to increment current asset supply %s)", swap.Amount[0].Denom), "", false, nil), nil, nil
|
||||
}
|
||||
case types.Outgoing:
|
||||
err := k.DecrementOutgoingAssetSupply(cacheCtx, swap.Amount[0])
|
||||
if err != nil {
|
||||
return simulation.NewOperationMsgBasic(types.ModuleName, fmt.Sprintf("no-operation (could not claim - unable to decrement outgoing asset supply %s)", swap.Amount[0].Denom), "", false, nil), nil, nil
|
||||
}
|
||||
err = k.DecrementCurrentAssetSupply(cacheCtx, swap.Amount[0])
|
||||
if err != nil {
|
||||
return simulation.NewOperationMsgBasic(types.ModuleName, fmt.Sprintf("no-operation (could not claim - unable to decrement current asset supply %s)", swap.Amount[0].Denom), "", false, nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
asset, err := k.GetAsset(ctx, swap.Amount[0].Denom)
|
||||
if err != nil {
|
||||
return simulation.NewOperationMsgBasic(types.ModuleName, fmt.Sprintf("no-operation (could not claim - asset not found %s)", swap.Amount[0].Denom), "", false, nil), nil, nil
|
||||
}
|
||||
supply, found := k.GetAssetSupply(ctx, asset.Denom)
|
||||
if !found {
|
||||
return simulation.NewOperationMsgBasic(types.ModuleName, fmt.Sprintf("no-operation (could not claim - asset supply not found %s)", swap.Amount[0].Denom), "", false, nil), nil, nil
|
||||
}
|
||||
if asset.SupplyLimit.LT(supply.CurrentSupply.Amount.Add(swap.Amount[0].Amount)) {
|
||||
return simulation.NoOpMsg(types.ModuleName), nil, nil
|
||||
}
|
||||
|
||||
msg := types.NewMsgClaimAtomicSwap(acc.GetAddress(), swapID, randomNumber)
|
||||
fees, err := simulation.RandomFees(r, ctx, acc.SpendableCoins(ctx.BlockTime()))
|
||||
if err != nil {
|
||||
return simulation.NoOpMsg(types.ModuleName), nil, err
|
||||
}
|
||||
|
||||
tx := helpers.GenTx(
|
||||
[]sdk.Msg{msg},
|
||||
fees,
|
||||
@ -204,12 +260,10 @@ func operationClaimAtomicSwap(ak types.AccountKeeper, k keeper.Keeper, swapID []
|
||||
[]uint64{acc.GetSequence()},
|
||||
simAccount.PrivKey,
|
||||
)
|
||||
|
||||
_, result, err := app.Deliver(tx)
|
||||
if err != nil {
|
||||
return simulation.NoOpMsg(types.ModuleName), nil, err
|
||||
}
|
||||
|
||||
return simulation.NewOperationMsg(msg, true, result.Log), nil, nil
|
||||
}
|
||||
}
|
||||
@ -221,6 +275,22 @@ func operationRefundAtomicSwap(ak types.AccountKeeper, k keeper.Keeper, swapID [
|
||||
simAccount, _ := simulation.RandomAcc(r, accs)
|
||||
acc := ak.GetAccount(ctx, simAccount.Address)
|
||||
|
||||
swap, found := k.GetAtomicSwap(ctx, swapID)
|
||||
if !found {
|
||||
return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("cannot refund: swap with ID %s not found", swapID)
|
||||
}
|
||||
cacheCtx, _ := ctx.CacheContext()
|
||||
switch swap.Direction {
|
||||
case types.Incoming:
|
||||
if err := k.DecrementIncomingAssetSupply(cacheCtx, swap.Amount[0]); err != nil {
|
||||
return simulation.NewOperationMsgBasic(types.ModuleName, fmt.Sprintf("no-operation (could not refund - unable to decrement incoming asset supply %s)", swap.Amount[0].Denom), "", false, nil), nil, nil
|
||||
}
|
||||
case types.Outgoing:
|
||||
if err := k.DecrementOutgoingAssetSupply(cacheCtx, swap.Amount[0]); err != nil {
|
||||
return simulation.NewOperationMsgBasic(types.ModuleName, fmt.Sprintf("no-operation (could not refund - unable to decrement outgoing asset supply %s)", swap.Amount[0].Denom), "", false, nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
msg := types.NewMsgRefundAtomicSwap(acc.GetAddress(), swapID)
|
||||
|
||||
fees, err := simulation.RandomFees(r, ctx, acc.SpendableCoins(ctx.BlockTime()))
|
||||
@ -242,20 +312,19 @@ func operationRefundAtomicSwap(ak types.AccountKeeper, k keeper.Keeper, swapID [
|
||||
if err != nil {
|
||||
return simulation.NoOpMsg(types.ModuleName), nil, err
|
||||
}
|
||||
|
||||
return simulation.NewOperationMsg(msg, true, result.Log), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
// findValidAccountAssetSupplyPair finds an account for which the callback func returns true
|
||||
func findValidAccountAssetSupplyPair(accounts []simulation.Account, supplies types.AssetSupplies,
|
||||
cb func(simulation.Account, types.AssetSupply) bool) (simulation.Account, types.AssetSupply, bool) {
|
||||
for _, supply := range supplies {
|
||||
func findValidAccountAssetPair(accounts []simulation.Account, assets types.AssetParams,
|
||||
cb func(simulation.Account, types.AssetParam) bool) (simulation.Account, types.AssetParam, bool) {
|
||||
for _, asset := range assets {
|
||||
for _, acc := range accounts {
|
||||
if isValid := cb(acc, supply); isValid {
|
||||
return acc, supply, true
|
||||
if isValid := cb(acc, asset); isValid {
|
||||
return acc, asset, true
|
||||
}
|
||||
}
|
||||
}
|
||||
return simulation.Account{}, types.AssetSupply{}, false
|
||||
return simulation.Account{}, types.AssetParam{}, false
|
||||
}
|
||||
|
@ -10,55 +10,15 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
keyBnbDeputyAddress = "BnbDeputyAddress"
|
||||
keyBnbDeputyFixedFee = "BnbDeputyFixedFee"
|
||||
keyMinAmount = "MinAmount"
|
||||
keyMaxAmount = "MaxAmount"
|
||||
keyMinBlockLock = "MinBlockLock"
|
||||
keyMaxBlockLock = "MaxBlockLock"
|
||||
keySupportedAssets = "SupportedAssets"
|
||||
keyAssetParams = "AssetParams"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
func ParamChanges(r *rand.Rand) []simulation.ParamChange {
|
||||
// We generate MinBlockLock first because the result is required by GenMaxBlockLock()
|
||||
minBlockLockVal := GenMinBlockLock(r)
|
||||
minAmount := GenMinAmount(r)
|
||||
|
||||
return []simulation.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keyBnbDeputyAddress,
|
||||
simulation.NewSimParamChange(types.ModuleName, keyAssetParams,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenRandBnbDeputy(r).Address)
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyBnbDeputyFixedFee,
|
||||
func(r *rand.Rand) string {
|
||||
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,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", minBlockLockVal)
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyMaxBlockLock,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", GenMaxBlockLock(r, minBlockLockVal))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keySupportedAssets,
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%v\"", GenSupportedAssets(r))
|
||||
return fmt.Sprintf("\"%s\"", GenSupportedAssets(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ var (
|
||||
// ErrInsufficientAmount error for when a swap's amount cannot cover the deputy's fixed fee
|
||||
ErrInsufficientAmount = sdkerrors.Register(ModuleName, 4, "amount cannot cover the deputy fixed fee")
|
||||
// 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 found")
|
||||
// ErrAssetNotActive error for when an 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
|
||||
@ -41,6 +41,6 @@ var (
|
||||
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")
|
||||
// ErrInvalidOutgoingAccount error for when an outgoing swap has a recipient value that is not the deputy address
|
||||
ErrInvalidOutgoingAccount = sdkerrors.Register(ModuleName, 19, "invalid recipient address for outgoing swap")
|
||||
// ErrInvalidSwapAccount error for when a swap involves an invalid account
|
||||
ErrInvalidSwapAccount = sdkerrors.Register(ModuleName, 19, "atomic swap has invalid account")
|
||||
)
|
||||
|
@ -8,17 +8,17 @@ import (
|
||||
|
||||
// GenesisState - all bep3 state that must be provided at genesis
|
||||
type GenesisState struct {
|
||||
Params Params `json:"params" yaml:"params"`
|
||||
AtomicSwaps AtomicSwaps `json:"atomic_swaps" yaml:"atomic_swaps"`
|
||||
AssetSupplies AssetSupplies `json:"assets_supplies" yaml:"assets_supplies"`
|
||||
Params Params `json:"params" yaml:"params"`
|
||||
AtomicSwaps AtomicSwaps `json:"atomic_swaps" yaml:"atomic_swaps"`
|
||||
Supplies AssetSupplies `json:"supplies" yaml:"supplies"`
|
||||
}
|
||||
|
||||
// NewGenesisState creates a new GenesisState object
|
||||
func NewGenesisState(params Params, swaps AtomicSwaps, supplies AssetSupplies) GenesisState {
|
||||
return GenesisState{
|
||||
Params: params,
|
||||
AtomicSwaps: swaps,
|
||||
AssetSupplies: supplies,
|
||||
Params: params,
|
||||
AtomicSwaps: swaps,
|
||||
Supplies: supplies,
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,19 +49,6 @@ func (gs GenesisState) Validate() error {
|
||||
return err
|
||||
}
|
||||
|
||||
denoms := map[string]bool{}
|
||||
for _, asset := range gs.AssetSupplies {
|
||||
if denoms[asset.Denom] {
|
||||
return fmt.Errorf("found duplicate asset denom %s", asset.Denom)
|
||||
}
|
||||
|
||||
if err := asset.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
denoms[asset.Denom] = true
|
||||
}
|
||||
|
||||
ids := map[string]bool{}
|
||||
for _, swap := range gs.AtomicSwaps {
|
||||
if ids[hex.EncodeToString(swap.GetSwapID())] {
|
||||
@ -74,5 +61,16 @@ func (gs GenesisState) Validate() error {
|
||||
|
||||
ids[hex.EncodeToString(swap.GetSwapID())] = true
|
||||
}
|
||||
|
||||
supplyDenoms := map[string]bool{}
|
||||
for _, supply := range gs.Supplies {
|
||||
if err := supply.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
if supplyDenoms[supply.GetDenom()] {
|
||||
return fmt.Errorf("found duplicate denom in asset supplies %s", supply.GetDenom())
|
||||
}
|
||||
supplyDenoms[supply.GetDenom()] = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -24,14 +24,13 @@ func (suite *GenesisTestSuite) SetupTest() {
|
||||
coin := sdk.NewCoin("kava", sdk.OneInt())
|
||||
suite.swaps = atomicSwaps(10)
|
||||
|
||||
supply := types.NewAssetSupply("kava", coin, coin, coin, coin)
|
||||
supply := types.NewAssetSupply(coin, coin, coin)
|
||||
suite.supplies = types.AssetSupplies{supply}
|
||||
}
|
||||
|
||||
func (suite *GenesisTestSuite) TestValidate() {
|
||||
type args struct {
|
||||
swaps types.AtomicSwaps
|
||||
supplies types.AssetSupplies
|
||||
swaps types.AtomicSwaps
|
||||
}
|
||||
testCases := []struct {
|
||||
name string
|
||||
@ -41,74 +40,50 @@ func (suite *GenesisTestSuite) TestValidate() {
|
||||
{
|
||||
"default",
|
||||
args{
|
||||
swaps: types.AtomicSwaps{},
|
||||
supplies: types.AssetSupplies{},
|
||||
swaps: types.AtomicSwaps{},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"with swaps",
|
||||
args{
|
||||
swaps: suite.swaps,
|
||||
supplies: types.AssetSupplies{},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"with supplies",
|
||||
args{
|
||||
swaps: types.AtomicSwaps{},
|
||||
supplies: suite.supplies,
|
||||
swaps: suite.swaps,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"duplicate swaps",
|
||||
args{
|
||||
swaps: types.AtomicSwaps{suite.swaps[2], suite.swaps[2]},
|
||||
supplies: types.AssetSupplies{},
|
||||
swaps: types.AtomicSwaps{suite.swaps[2], suite.swaps[2]},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid swap",
|
||||
args{
|
||||
swaps: types.AtomicSwaps{types.AtomicSwap{Amount: sdk.Coins{sdk.Coin{Denom: "Invalid Denom", Amount: sdk.NewInt(-1)}}}},
|
||||
supplies: types.AssetSupplies{},
|
||||
swaps: types.AtomicSwaps{types.AtomicSwap{Amount: sdk.Coins{sdk.Coin{Denom: "Invalid Denom", Amount: sdk.NewInt(-1)}}}},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid supply",
|
||||
args{
|
||||
swaps: types.AtomicSwaps{},
|
||||
supplies: types.AssetSupplies{types.AssetSupply{Denom: "Invalid Denom"}},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"duplicate supplies",
|
||||
args{
|
||||
swaps: types.AtomicSwaps{},
|
||||
supplies: types.AssetSupplies{suite.supplies[0], suite.supplies[0]},
|
||||
},
|
||||
false,
|
||||
}}
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
var gs types.GenesisState
|
||||
if tc.name == "default" {
|
||||
gs = types.DefaultGenesisState()
|
||||
} else {
|
||||
gs = types.NewGenesisState(types.DefaultParams(), tc.args.swaps, tc.args.supplies)
|
||||
}
|
||||
suite.Run(tc.name, func() {
|
||||
var gs types.GenesisState
|
||||
if tc.name == "default" {
|
||||
gs = types.DefaultGenesisState()
|
||||
} else {
|
||||
gs = types.NewGenesisState(types.DefaultParams(), tc.args.swaps, suite.supplies)
|
||||
}
|
||||
|
||||
err := gs.Validate()
|
||||
if tc.expectPass {
|
||||
suite.Require().NoError(err, tc.name)
|
||||
} else {
|
||||
suite.Require().Error(err, tc.name)
|
||||
}
|
||||
err := gs.Validate()
|
||||
if tc.expectPass {
|
||||
suite.Require().NoError(err, tc.name)
|
||||
} else {
|
||||
suite.Require().Error(err, tc.name)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
@ -28,13 +26,10 @@ const (
|
||||
|
||||
// Key prefixes
|
||||
var (
|
||||
// SupplyLimitUpgradeTime is the block time after which the asset supply limits are updated from params
|
||||
SupplyLimitUpgradeTime time.Time = time.Date(2020, 7, 10, 14, 0, 0, 0, time.UTC)
|
||||
|
||||
AtomicSwapKeyPrefix = []byte{0x00} // prefix for keys that store AtomicSwaps
|
||||
AtomicSwapByBlockPrefix = []byte{0x01} // prefix for keys of the AtomicSwapsByBlock index
|
||||
AssetSupplyKeyPrefix = []byte{0x02} // prefix for keys that store global asset supply counts
|
||||
AtomicSwapLongtermStoragePrefix = []byte{0x03} // prefix for keys of the AtomicSwapLongtermStorage index
|
||||
AtomicSwapLongtermStoragePrefix = []byte{0x02} // prefix for keys of the AtomicSwapLongtermStorage index
|
||||
AssetSupplyPrefix = []byte{0x03}
|
||||
)
|
||||
|
||||
// GetAtomicSwapByHeightKey is used by the AtomicSwapByBlock index and AtomicSwapLongtermStorage index
|
||||
|
@ -1,100 +1,80 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
)
|
||||
|
||||
const (
|
||||
bech32MainPrefix = "kava"
|
||||
)
|
||||
|
||||
// Parameter keys
|
||||
var (
|
||||
KeyBnbDeputyAddress = []byte("BnbDeputyAddress")
|
||||
KeyBnbDeputyFixedFee = []byte("BnbDeputyFixedFee")
|
||||
KeyMinAmount = []byte("MinAmount")
|
||||
KeyMaxAmount = []byte("MaxAmount")
|
||||
KeyMinBlockLock = []byte("MinBlockLock")
|
||||
KeyMaxBlockLock = []byte("MaxBlockLock")
|
||||
KeySupportedAssets = []byte("SupportedAssets")
|
||||
KeyAssetParams = []byte("AssetParams")
|
||||
|
||||
DefaultBnbDeputyFixedFee sdk.Int = sdk.NewInt(1000) // 0.00001 BNB
|
||||
DefaultMinAmount sdk.Int = sdk.ZeroInt()
|
||||
DefaultMaxAmount sdk.Int = sdk.NewInt(1000000000000) // 10,000 BNB
|
||||
DefaultMinBlockLock uint64 = 220
|
||||
DefaultMaxBlockLock uint64 = 270
|
||||
DefaultSupportedAssets = AssetParams{
|
||||
AssetParam{
|
||||
Denom: "bnb",
|
||||
CoinID: 714,
|
||||
Limit: sdk.NewInt(350000000000000), // 3,500,000 BNB
|
||||
Active: true,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Params governance parameters for bep3 module
|
||||
type Params struct {
|
||||
BnbDeputyAddress sdk.AccAddress `json:"bnb_deputy_address" yaml:"bnb_deputy_address"` // Bnbchain deputy address
|
||||
BnbDeputyFixedFee sdk.Int `json:"bnb_deputy_fixed_fee" yaml:"bnb_deputy_fixed_fee"` // Deputy fixed fee in BNB
|
||||
MinAmount sdk.Int `json:"min_amount" yaml:"min_amount"` // Minimum swap amount
|
||||
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
|
||||
AssetParams AssetParams `json:"asset_params" yaml:"asset_params"`
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer
|
||||
func (p Params) String() string {
|
||||
return fmt.Sprintf(`Params:
|
||||
Bnbchain deputy address: %s,
|
||||
Deputy fixed fee (BNB): %d,
|
||||
Min amount: %d,
|
||||
Max amount: %d,
|
||||
Min block lock: %d,
|
||||
Max block lock: %d,
|
||||
Supported assets: %s`,
|
||||
p.BnbDeputyAddress.String(), p.BnbDeputyFixedFee, p.MinAmount,
|
||||
p.MaxAmount, p.MinBlockLock, p.MaxBlockLock, p.SupportedAssets)
|
||||
AssetParams: %s`,
|
||||
p.AssetParams)
|
||||
}
|
||||
|
||||
// NewParams returns a new params object
|
||||
func NewParams(bnbDeputyAddress sdk.AccAddress, bnbDeputyFixedFee, minAmount,
|
||||
maxAmount sdk.Int, minBlockLock, maxBlockLock uint64, supportedAssets AssetParams,
|
||||
func NewParams(ap AssetParams,
|
||||
) Params {
|
||||
return Params{
|
||||
BnbDeputyAddress: bnbDeputyAddress,
|
||||
BnbDeputyFixedFee: bnbDeputyFixedFee,
|
||||
MinAmount: minAmount,
|
||||
MaxAmount: maxAmount,
|
||||
MinBlockLock: minBlockLock,
|
||||
MaxBlockLock: maxBlockLock,
|
||||
SupportedAssets: supportedAssets,
|
||||
AssetParams: ap,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultParams returns default params for bep3 module
|
||||
func DefaultParams() Params {
|
||||
defaultBnbDeputyAddress, err := sdk.AccAddressFromBech32("kava1r4v2zdhdalfj2ydazallqvrus9fkphmglhn6u6")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return NewParams(defaultBnbDeputyAddress, DefaultBnbDeputyFixedFee, DefaultMinAmount,
|
||||
DefaultMaxAmount, DefaultMinBlockLock, DefaultMaxBlockLock, DefaultSupportedAssets)
|
||||
return NewParams(AssetParams{})
|
||||
}
|
||||
|
||||
// AssetParam governance parameters for each asset within a supported chain
|
||||
// AssetParam parameters that must be specified for each bep3 asset
|
||||
type AssetParam struct {
|
||||
Denom string `json:"denom" yaml:"denom"` // name of the asset
|
||||
CoinID int `json:"coin_id" yaml:"coin_id"` // internationally recognized coin ID
|
||||
Limit sdk.Int `json:"limit" yaml:"limit"` // asset supply limit
|
||||
Active bool `json:"active" yaml:"active"` // denotes if asset is available or paused
|
||||
Denom string `json:"denom" yaml:"denom"` // name of the asset
|
||||
CoinID int `json:"coin_id" yaml:"coin_id"` // SLIP-0044 registered coin type - see https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
||||
SupplyLimit sdk.Int `json:"supply_limit" yaml:"supply_limit"` // asset supply limit
|
||||
Active bool `json:"active" yaml:"active"` // denotes if asset is available or paused
|
||||
DeputyAddress sdk.AccAddress `json:"deputy_address" yaml:"deputy_address"` // the address of the relayer process
|
||||
FixedFee sdk.Int `json:"fixed_fee" yaml:"fixed_fee"` // the fixed fee charged by the relayer process for outgoing swaps
|
||||
MinSwapAmount sdk.Int `json:"min_swap_amount" yaml:"min_swap_amount"` // Minimum swap amount
|
||||
MaxSwapAmount sdk.Int `json:"max_swap_amount" yaml:"max_swap_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
|
||||
}
|
||||
|
||||
// NewAssetParam returns a new AssetParam
|
||||
func NewAssetParam(
|
||||
denom string, coinID int, limit sdk.Int, active bool,
|
||||
deputyAddr sdk.AccAddress, fixedFee sdk.Int, minSwapAmount sdk.Int,
|
||||
maxSwapAmount sdk.Int, minBlockLock uint64, maxBlockLock uint64,
|
||||
) AssetParam {
|
||||
return AssetParam{
|
||||
Denom: denom,
|
||||
CoinID: coinID,
|
||||
SupplyLimit: limit,
|
||||
Active: active,
|
||||
DeputyAddress: deputyAddr,
|
||||
FixedFee: fixedFee,
|
||||
MinSwapAmount: minSwapAmount,
|
||||
MaxSwapAmount: maxSwapAmount,
|
||||
MinBlockLock: minBlockLock,
|
||||
MaxBlockLock: maxBlockLock,
|
||||
}
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer
|
||||
@ -103,8 +83,15 @@ func (ap AssetParam) String() string {
|
||||
Denom: %s
|
||||
Coin ID: %d
|
||||
Limit: %s
|
||||
Active: %t`,
|
||||
ap.Denom, ap.CoinID, ap.Limit.String(), ap.Active)
|
||||
Active: %t
|
||||
Deputy Address: %s
|
||||
Fixed Fee: %s
|
||||
Min Swap Amount: %s
|
||||
Max Swap Amount: %s
|
||||
Min Block Lock: %d
|
||||
Max Block Lock: %d`,
|
||||
ap.Denom, ap.CoinID, ap.SupplyLimit, ap.Active, ap.DeputyAddress, ap.FixedFee,
|
||||
ap.MinSwapAmount, ap.MaxSwapAmount, ap.MinBlockLock, ap.MaxBlockLock)
|
||||
}
|
||||
|
||||
// AssetParams array of AssetParam
|
||||
@ -129,149 +116,69 @@ func ParamKeyTable() params.KeyTable {
|
||||
// nolint
|
||||
func (p *Params) ParamSetPairs() params.ParamSetPairs {
|
||||
return params.ParamSetPairs{
|
||||
params.NewParamSetPair(KeyBnbDeputyAddress, &p.BnbDeputyAddress, validateBnbDeputyAddressParam),
|
||||
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(KeyMaxBlockLock, &p.MaxBlockLock, validateMaxBlockLockParam),
|
||||
params.NewParamSetPair(KeySupportedAssets, &p.SupportedAssets, validateSupportedAssetsParams),
|
||||
params.NewParamSetPair(KeyAssetParams, &p.AssetParams, validateAssetParams),
|
||||
}
|
||||
}
|
||||
|
||||
// Validate ensure that params have valid values
|
||||
func (p Params) Validate() error {
|
||||
if err := validateBnbDeputyAddressParam(p.BnbDeputyAddress); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateBnbDeputyFixedFeeParam(p.BnbDeputyFixedFee); err != nil {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateMaxBlockLockParam(p.MaxBlockLock); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if 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 validateAssetParams(p.AssetParams)
|
||||
}
|
||||
|
||||
func validateBnbDeputyAddressParam(i interface{}) error {
|
||||
addr, ok := i.(sdk.AccAddress)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
if addr.Empty() {
|
||||
return errors.New("bnb deputy address cannot be empty")
|
||||
}
|
||||
|
||||
if len(addr.Bytes()) != sdk.AddrLen {
|
||||
return fmt.Errorf("bnb deputy address invalid bytes length got %d, want %d", len(addr.Bytes()), sdk.AddrLen)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateBnbDeputyFixedFeeParam(i interface{}) error {
|
||||
_, 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 {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateMinBlockLockParam(i interface{}) error {
|
||||
_, ok := i.(uint64)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateMaxBlockLockParam(i interface{}) error {
|
||||
_, ok := i.(uint64)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateSupportedAssetsParams(i interface{}) error {
|
||||
func validateAssetParams(i interface{}) error {
|
||||
assetParams, ok := i.(AssetParams)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
coinIDs := make(map[int]bool)
|
||||
coinDenoms := make(map[string]bool)
|
||||
for _, asset := range assetParams {
|
||||
if strings.TrimSpace(asset.Denom) == "" {
|
||||
return errors.New("asset denom cannot be empty")
|
||||
if err := sdk.ValidateDenom(asset.Denom); err != nil {
|
||||
return fmt.Errorf("asset denom invalid: %s", asset.Denom)
|
||||
}
|
||||
|
||||
if asset.CoinID < 0 {
|
||||
return fmt.Errorf(fmt.Sprintf("asset %s must be a non negative integer", asset.Denom))
|
||||
return fmt.Errorf("asset %s coin id must be a non negative integer", asset.Denom)
|
||||
}
|
||||
|
||||
if !asset.Limit.IsPositive() {
|
||||
return fmt.Errorf(fmt.Sprintf("asset %s must have a positive supply limit", asset.Denom))
|
||||
if asset.SupplyLimit.IsNegative() {
|
||||
return fmt.Errorf("asset %s has invalid (negative) supply limit: %s", asset.Denom, asset.SupplyLimit)
|
||||
}
|
||||
|
||||
_, found := coinDenoms[asset.Denom]
|
||||
if found {
|
||||
return fmt.Errorf(fmt.Sprintf("asset %s cannot have duplicate denom", asset.Denom))
|
||||
return fmt.Errorf("asset %s cannot have duplicate denom", asset.Denom)
|
||||
}
|
||||
|
||||
coinDenoms[asset.Denom] = true
|
||||
|
||||
_, found = coinIDs[asset.CoinID]
|
||||
if found {
|
||||
return fmt.Errorf(fmt.Sprintf("asset %s cannot have duplicate coin id %d", asset.Denom, asset.CoinID))
|
||||
if asset.DeputyAddress.Empty() {
|
||||
return fmt.Errorf("deputy address cannot be empty for %s", asset.Denom)
|
||||
}
|
||||
|
||||
coinIDs[asset.CoinID] = true
|
||||
if len(asset.DeputyAddress.Bytes()) != sdk.AddrLen {
|
||||
return fmt.Errorf("%s deputy address invalid bytes length got %d, want %d", asset.Denom, len(asset.DeputyAddress.Bytes()), sdk.AddrLen)
|
||||
}
|
||||
|
||||
if asset.FixedFee.IsNegative() {
|
||||
return fmt.Errorf("asset %s cannot have a negative fixed fee %s", asset.Denom, asset.FixedFee)
|
||||
}
|
||||
|
||||
if asset.MinBlockLock > asset.MaxBlockLock {
|
||||
return fmt.Errorf("asset %s has minimum block lock > maximum block lock %d > %d", asset.Denom, asset.MinBlockLock, asset.MaxBlockLock)
|
||||
}
|
||||
|
||||
if !asset.MinSwapAmount.IsPositive() {
|
||||
return fmt.Errorf("asset %s must have a positive minimum swap amount, got %s", asset.Denom, asset.MinSwapAmount)
|
||||
}
|
||||
|
||||
if !asset.MaxSwapAmount.IsPositive() {
|
||||
return fmt.Errorf("asset %s must have a positive maximum swap amount, got %s", asset.Denom, asset.MaxSwapAmount)
|
||||
}
|
||||
|
||||
if asset.MinSwapAmount.GT(asset.MaxSwapAmount) {
|
||||
return fmt.Errorf("asset %s has minimum swap amount > maximum swap amount %s > %s", asset.Denom, asset.MinSwapAmount, asset.MaxSwapAmount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -13,7 +13,8 @@ import (
|
||||
|
||||
type ParamsTestSuite struct {
|
||||
suite.Suite
|
||||
addr sdk.AccAddress
|
||||
addr sdk.AccAddress
|
||||
supply []sdk.Int
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) SetupTest() {
|
||||
@ -21,20 +22,14 @@ func (suite *ParamsTestSuite) SetupTest() {
|
||||
app.SetBech32AddressPrefixes(config)
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(1)
|
||||
suite.addr = addrs[0]
|
||||
suite.supply = append(suite.supply, sdk.NewInt(10000000000000), sdk.NewInt(10000000000000))
|
||||
return
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) TestParamValidation() {
|
||||
type LoadParams func() types.Params
|
||||
|
||||
type args struct {
|
||||
bnbDeputyAddress sdk.AccAddress
|
||||
bnbDeputyFixedFee sdk.Int
|
||||
minAmount sdk.Int
|
||||
maxAmount sdk.Int
|
||||
minBlockLock uint64
|
||||
maxBlockLock uint64
|
||||
supportedAssets types.AssetParams
|
||||
assetParams types.AssetParams
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
@ -46,189 +41,168 @@ func (suite *ParamsTestSuite) TestParamValidation() {
|
||||
{
|
||||
name: "default",
|
||||
args: args{
|
||||
bnbDeputyAddress: suite.addr,
|
||||
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
|
||||
minAmount: types.DefaultMinAmount,
|
||||
maxAmount: types.DefaultMaxAmount,
|
||||
minBlockLock: types.DefaultMinBlockLock,
|
||||
maxBlockLock: types.DefaultMaxBlockLock,
|
||||
supportedAssets: types.DefaultSupportedAssets,
|
||||
assetParams: types.AssetParams{},
|
||||
},
|
||||
expectPass: true,
|
||||
expectedErr: "",
|
||||
},
|
||||
{
|
||||
name: "minimum block lock == maximum block lock",
|
||||
name: "valid single asset",
|
||||
args: args{
|
||||
bnbDeputyAddress: suite.addr,
|
||||
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
|
||||
minAmount: types.DefaultMinAmount,
|
||||
maxAmount: types.DefaultMaxAmount,
|
||||
minBlockLock: 243,
|
||||
maxBlockLock: 243,
|
||||
supportedAssets: types.DefaultSupportedAssets,
|
||||
assetParams: types.AssetParams{types.NewAssetParam(
|
||||
"bnb", 714, suite.supply[0], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(100000000), sdk.NewInt(100000000000),
|
||||
types.DefaultMinBlockLock, types.DefaultMaxBlockLock)},
|
||||
},
|
||||
expectPass: true,
|
||||
expectedErr: "",
|
||||
},
|
||||
{
|
||||
name: "minimum amount greater than maximum amount",
|
||||
name: "valid multi asset",
|
||||
args: args{
|
||||
bnbDeputyAddress: suite.addr,
|
||||
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
|
||||
minAmount: sdk.NewInt(10000000),
|
||||
maxAmount: sdk.NewInt(100000),
|
||||
minBlockLock: types.DefaultMinBlockLock,
|
||||
maxBlockLock: types.DefaultMaxBlockLock,
|
||||
supportedAssets: types.DefaultSupportedAssets,
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "minimum amount cannot be > maximum amount",
|
||||
},
|
||||
{
|
||||
name: "minimum block lock greater than maximum block lock",
|
||||
args: args{
|
||||
bnbDeputyAddress: suite.addr,
|
||||
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
|
||||
minAmount: types.DefaultMinAmount,
|
||||
maxAmount: types.DefaultMaxAmount,
|
||||
minBlockLock: 500,
|
||||
maxBlockLock: 400,
|
||||
supportedAssets: types.DefaultSupportedAssets,
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "minimum block lock cannot be > maximum block lock",
|
||||
},
|
||||
{
|
||||
name: "empty asset denom",
|
||||
args: args{
|
||||
bnbDeputyAddress: suite.addr,
|
||||
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
|
||||
minAmount: types.DefaultMinAmount,
|
||||
maxAmount: types.DefaultMaxAmount,
|
||||
minBlockLock: types.DefaultMinBlockLock,
|
||||
maxBlockLock: types.DefaultMaxBlockLock,
|
||||
supportedAssets: types.AssetParams{
|
||||
types.AssetParam{
|
||||
Denom: "",
|
||||
CoinID: 714,
|
||||
Limit: sdk.NewInt(100000000000),
|
||||
Active: true,
|
||||
},
|
||||
assetParams: types.AssetParams{types.NewAssetParam(
|
||||
"bnb", 714, suite.supply[0], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(100000000), sdk.NewInt(100000000000),
|
||||
types.DefaultMinBlockLock, types.DefaultMaxBlockLock),
|
||||
types.NewAssetParam(
|
||||
"btcb", 0, suite.supply[1], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(10000000), sdk.NewInt(100000000000),
|
||||
types.DefaultMinBlockLock, types.DefaultMaxBlockLock),
|
||||
},
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "asset denom cannot be empty",
|
||||
expectPass: true,
|
||||
expectedErr: "",
|
||||
},
|
||||
{
|
||||
name: "negative asset coin ID",
|
||||
name: "invalid denom - empty",
|
||||
args: args{
|
||||
bnbDeputyAddress: suite.addr,
|
||||
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
|
||||
minAmount: types.DefaultMinAmount,
|
||||
maxAmount: types.DefaultMaxAmount,
|
||||
minBlockLock: types.DefaultMinBlockLock,
|
||||
maxBlockLock: types.DefaultMaxBlockLock,
|
||||
supportedAssets: types.AssetParams{
|
||||
types.AssetParam{
|
||||
Denom: "bnb",
|
||||
CoinID: -1,
|
||||
Limit: sdk.NewInt(100000000000),
|
||||
Active: true,
|
||||
},
|
||||
},
|
||||
assetParams: types.AssetParams{types.NewAssetParam(
|
||||
"", 714, suite.supply[0], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(100000000), sdk.NewInt(100000000000),
|
||||
types.DefaultMinBlockLock, types.DefaultMaxBlockLock)},
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "must be a non negative integer",
|
||||
expectedErr: "denom invalid",
|
||||
},
|
||||
{
|
||||
name: "invalid denom - bad format",
|
||||
args: args{
|
||||
assetParams: types.AssetParams{types.NewAssetParam(
|
||||
"BNB", 714, suite.supply[0], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(100000000), sdk.NewInt(100000000000),
|
||||
types.DefaultMinBlockLock, types.DefaultMaxBlockLock)},
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "denom invalid",
|
||||
},
|
||||
{
|
||||
name: "min block lock equal max block lock",
|
||||
args: args{
|
||||
assetParams: types.AssetParams{types.NewAssetParam(
|
||||
"bnb", 714, suite.supply[0], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(100000000), sdk.NewInt(100000000000),
|
||||
243, 243)},
|
||||
},
|
||||
expectPass: true,
|
||||
expectedErr: "",
|
||||
},
|
||||
{
|
||||
name: "min block lock greater max block lock",
|
||||
args: args{
|
||||
assetParams: types.AssetParams{types.NewAssetParam(
|
||||
"bnb", 714, suite.supply[0], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(100000000), sdk.NewInt(100000000000),
|
||||
244, 243)},
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "minimum block lock > maximum block lock",
|
||||
},
|
||||
{
|
||||
name: "min swap not positive",
|
||||
args: args{
|
||||
assetParams: types.AssetParams{types.NewAssetParam(
|
||||
"bnb", 714, suite.supply[0], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(0), sdk.NewInt(10000000000),
|
||||
types.DefaultMinBlockLock, types.DefaultMaxBlockLock)},
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "must have a positive minimum swap",
|
||||
},
|
||||
{
|
||||
name: "max swap not positive",
|
||||
args: args{
|
||||
assetParams: types.AssetParams{types.NewAssetParam(
|
||||
"bnb", 714, suite.supply[0], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(10000), sdk.NewInt(0),
|
||||
types.DefaultMinBlockLock, types.DefaultMaxBlockLock)},
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "must have a positive maximum swap",
|
||||
},
|
||||
{
|
||||
name: "min swap greater max swap",
|
||||
args: args{
|
||||
assetParams: types.AssetParams{types.NewAssetParam(
|
||||
"bnb", 714, suite.supply[0], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(100000000000), sdk.NewInt(10000000000),
|
||||
types.DefaultMinBlockLock, types.DefaultMaxBlockLock)},
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "minimum swap amount > maximum swap amount",
|
||||
},
|
||||
{
|
||||
name: "negative coin id",
|
||||
args: args{
|
||||
assetParams: types.AssetParams{types.NewAssetParam(
|
||||
"bnb", -714, suite.supply[0], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(100000000), sdk.NewInt(100000000000),
|
||||
types.DefaultMinBlockLock, types.DefaultMaxBlockLock)},
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "coin id must be a non negative",
|
||||
},
|
||||
{
|
||||
name: "negative asset limit",
|
||||
args: args{
|
||||
bnbDeputyAddress: suite.addr,
|
||||
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
|
||||
minAmount: types.DefaultMinAmount,
|
||||
maxAmount: types.DefaultMaxAmount,
|
||||
minBlockLock: types.DefaultMinBlockLock,
|
||||
maxBlockLock: types.DefaultMaxBlockLock,
|
||||
supportedAssets: types.AssetParams{
|
||||
types.AssetParam{
|
||||
Denom: "bnb",
|
||||
CoinID: 714,
|
||||
Limit: sdk.NewInt(-10000),
|
||||
Active: true,
|
||||
},
|
||||
},
|
||||
assetParams: types.AssetParams{types.NewAssetParam(
|
||||
"bnb", 714,
|
||||
sdk.NewInt(-10000000000000), true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(100000000), sdk.NewInt(100000000000),
|
||||
types.DefaultMinBlockLock, types.DefaultMaxBlockLock)},
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "must have a positive supply limit",
|
||||
expectedErr: "invalid (negative) supply limit",
|
||||
},
|
||||
{
|
||||
name: "duplicate asset denom",
|
||||
name: "duplicate denom",
|
||||
args: args{
|
||||
bnbDeputyAddress: suite.addr,
|
||||
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
|
||||
minAmount: types.DefaultMinAmount,
|
||||
maxAmount: types.DefaultMaxAmount,
|
||||
minBlockLock: types.DefaultMinBlockLock,
|
||||
maxBlockLock: types.DefaultMaxBlockLock,
|
||||
supportedAssets: types.AssetParams{
|
||||
types.AssetParam{
|
||||
Denom: "bnb",
|
||||
CoinID: 714,
|
||||
Limit: sdk.NewInt(100000000000),
|
||||
Active: true,
|
||||
},
|
||||
types.AssetParam{
|
||||
Denom: "bnb",
|
||||
CoinID: 114,
|
||||
Limit: sdk.NewInt(500000000),
|
||||
Active: false,
|
||||
},
|
||||
assetParams: types.AssetParams{types.NewAssetParam(
|
||||
"bnb", 714, suite.supply[0], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(100000000), sdk.NewInt(100000000000),
|
||||
types.DefaultMinBlockLock, types.DefaultMaxBlockLock),
|
||||
types.NewAssetParam(
|
||||
"bnb", 0, suite.supply[0], true,
|
||||
suite.addr, sdk.NewInt(1000), sdk.NewInt(10000000), sdk.NewInt(100000000000),
|
||||
types.DefaultMinBlockLock, types.DefaultMaxBlockLock),
|
||||
},
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "cannot have duplicate denom",
|
||||
},
|
||||
{
|
||||
name: "duplicate asset coin ID",
|
||||
args: args{
|
||||
bnbDeputyAddress: suite.addr,
|
||||
bnbDeputyFixedFee: types.DefaultBnbDeputyFixedFee,
|
||||
minAmount: types.DefaultMinAmount,
|
||||
maxAmount: types.DefaultMaxAmount,
|
||||
minBlockLock: types.DefaultMinBlockLock,
|
||||
maxBlockLock: types.DefaultMaxBlockLock,
|
||||
supportedAssets: types.AssetParams{
|
||||
types.AssetParam{
|
||||
Denom: "bnb",
|
||||
CoinID: 714,
|
||||
Limit: sdk.NewInt(100000000000),
|
||||
Active: true,
|
||||
},
|
||||
types.AssetParam{
|
||||
Denom: "fake",
|
||||
CoinID: 714,
|
||||
Limit: sdk.NewInt(500000000),
|
||||
Active: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectPass: false,
|
||||
expectedErr: "cannot have duplicate coin id",
|
||||
expectedErr: "duplicate denom",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
params := types.NewParams(tc.args.bnbDeputyAddress, tc.args.bnbDeputyFixedFee, tc.args.minAmount,
|
||||
tc.args.maxAmount, tc.args.minBlockLock, tc.args.maxBlockLock, tc.args.supportedAssets)
|
||||
suite.Run(tc.name, func() {
|
||||
params := types.NewParams(tc.args.assetParams)
|
||||
err := params.Validate()
|
||||
if tc.expectPass {
|
||||
suite.Require().NoError(err, tc.name)
|
||||
} else {
|
||||
suite.Require().Error(err, tc.name)
|
||||
suite.Require().Contains(err.Error(), tc.expectedErr)
|
||||
}
|
||||
|
||||
err := params.Validate()
|
||||
if tc.expectPass {
|
||||
suite.Require().NoError(err, tc.name)
|
||||
} else {
|
||||
suite.Require().Error(err, tc.name)
|
||||
suite.Require().Contains(err.Error(), tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,11 @@ const (
|
||||
|
||||
// QueryAssetSupply contains the params for query 'custom/bep3/supply'
|
||||
type QueryAssetSupply struct {
|
||||
Denom tmbytes.HexBytes `json:"denom" yaml:"denom"`
|
||||
Denom string `json:"denom" yaml:"denom"`
|
||||
}
|
||||
|
||||
// NewQueryAssetSupply creates a new QueryAssetSupply
|
||||
func NewQueryAssetSupply(denom tmbytes.HexBytes) QueryAssetSupply {
|
||||
func NewQueryAssetSupply(denom string) QueryAssetSupply {
|
||||
return QueryAssetSupply{
|
||||
Denom: denom,
|
||||
}
|
||||
|
@ -9,21 +9,17 @@ import (
|
||||
|
||||
// AssetSupply contains information about an asset's supply
|
||||
type AssetSupply struct {
|
||||
Denom string `json:"denom" yaml:"denom"`
|
||||
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"`
|
||||
SupplyLimit sdk.Coin `json:"supply_limit" yaml:"supply_limit"`
|
||||
}
|
||||
|
||||
// NewAssetSupply initializes a new AssetSupply
|
||||
func NewAssetSupply(denom string, incomingSupply, outgoingSupply, currentSupply, supplyLimit sdk.Coin) AssetSupply {
|
||||
func NewAssetSupply(incomingSupply, outgoingSupply, currentSupply sdk.Coin) AssetSupply {
|
||||
return AssetSupply{
|
||||
Denom: denom,
|
||||
IncomingSupply: incomingSupply,
|
||||
OutgoingSupply: outgoingSupply,
|
||||
CurrentSupply: currentSupply,
|
||||
SupplyLimit: supplyLimit,
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,22 +34,35 @@ func (a AssetSupply) Validate() error {
|
||||
if !a.CurrentSupply.IsValid() {
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "current supply %s", a.CurrentSupply)
|
||||
}
|
||||
if !a.SupplyLimit.IsValid() {
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "supply limit %s", a.SupplyLimit)
|
||||
denom := a.CurrentSupply.Denom
|
||||
if (a.IncomingSupply.Denom != denom) ||
|
||||
(a.OutgoingSupply.Denom != denom) {
|
||||
return fmt.Errorf("asset supply denoms do not match %s %s %s", a.CurrentSupply.Denom, a.IncomingSupply.Denom, a.OutgoingSupply.Denom)
|
||||
}
|
||||
return sdk.ValidateDenom(a.Denom)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Equal returns if two asset supplies are equal
|
||||
func (a AssetSupply) Equal(b AssetSupply) bool {
|
||||
return (a.IncomingSupply.IsEqual(b.IncomingSupply) &&
|
||||
a.CurrentSupply.IsEqual(b.CurrentSupply) &&
|
||||
a.OutgoingSupply.IsEqual(b.OutgoingSupply))
|
||||
}
|
||||
|
||||
// String implements stringer
|
||||
func (a AssetSupply) String() string {
|
||||
return fmt.Sprintf(`
|
||||
%s supply:
|
||||
asset supply:
|
||||
Incoming supply: %s
|
||||
Outgoing supply: %s
|
||||
Current supply: %s
|
||||
Supply limit: %s
|
||||
`,
|
||||
a.Denom, a.IncomingSupply, a.OutgoingSupply, a.CurrentSupply, a.SupplyLimit)
|
||||
a.IncomingSupply, a.OutgoingSupply, a.CurrentSupply)
|
||||
}
|
||||
|
||||
// GetDenom getter method for the denom of the asset supply
|
||||
func (a AssetSupply) GetDenom() string {
|
||||
return a.CurrentSupply.Denom
|
||||
}
|
||||
|
||||
// AssetSupplies is a slice of AssetSupply
|
@ -17,7 +17,7 @@ func TestAssetSupplyValidate(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
msg: "valid asset",
|
||||
asset: NewAssetSupply("kava", coin, coin, coin, coin),
|
||||
asset: NewAssetSupply(coin, coin, coin),
|
||||
expPass: true,
|
||||
},
|
||||
{
|
||||
@ -42,21 +42,6 @@ func TestAssetSupplyValidate(t *testing.T) {
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid supply limit",
|
||||
AssetSupply{
|
||||
IncomingSupply: coin,
|
||||
OutgoingSupply: coin,
|
||||
CurrentSupply: coin,
|
||||
SupplyLimit: invalidCoin,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
msg: "invalid denom",
|
||||
asset: NewAssetSupply("Invalid Denom", coin, coin, coin, coin),
|
||||
expPass: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
@ -76,19 +76,33 @@ func (suite *PermissionTestSuite) TestSubParamChangePermission_Allows() {
|
||||
testCDPParams.DebtParam = testDP
|
||||
testCDPParams.GlobalDebtLimit = testCPs[0].DebtLimit.Add(testCPs[0].DebtLimit) // correct global debt limit to pass genesis validation
|
||||
|
||||
testDeputy, err := sdk.AccAddressFromBech32("kava1xy7hrjy9r0algz9w3gzm8u6mrpq97kwta747gj")
|
||||
suite.Require().NoError(err)
|
||||
// bep3 Asset Params
|
||||
testAPs := bep3types.AssetParams{
|
||||
{
|
||||
Denom: "bnb",
|
||||
CoinID: 714,
|
||||
Limit: i(100000000000),
|
||||
Active: true,
|
||||
bep3types.AssetParam{
|
||||
Denom: "bnb",
|
||||
CoinID: 714,
|
||||
SupplyLimit: sdk.NewInt(350000000000000),
|
||||
Active: true,
|
||||
DeputyAddress: testDeputy,
|
||||
FixedFee: sdk.NewInt(1000),
|
||||
MinSwapAmount: sdk.OneInt(),
|
||||
MaxSwapAmount: sdk.NewInt(1000000000000),
|
||||
MinBlockLock: bep3types.DefaultMinBlockLock,
|
||||
MaxBlockLock: bep3types.DefaultMaxBlockLock,
|
||||
},
|
||||
{
|
||||
Denom: "inc",
|
||||
CoinID: 9999,
|
||||
Limit: i(100),
|
||||
Active: false,
|
||||
bep3types.AssetParam{
|
||||
Denom: "inc",
|
||||
CoinID: 9999,
|
||||
SupplyLimit: sdk.NewInt(100),
|
||||
Active: false,
|
||||
DeputyAddress: testDeputy,
|
||||
FixedFee: sdk.NewInt(1000),
|
||||
MinSwapAmount: sdk.OneInt(),
|
||||
MaxSwapAmount: sdk.NewInt(1000000000000),
|
||||
MinBlockLock: bep3types.DefaultMinBlockLock,
|
||||
MaxBlockLock: bep3types.DefaultMaxBlockLock,
|
||||
},
|
||||
}
|
||||
testAPsUpdatedActive := make(bep3types.AssetParams, len(testAPs))
|
||||
@ -97,7 +111,7 @@ func (suite *PermissionTestSuite) TestSubParamChangePermission_Allows() {
|
||||
|
||||
// bep3 Genesis
|
||||
testBep3Params := bep3types.DefaultParams()
|
||||
testBep3Params.SupportedAssets = testAPs
|
||||
testBep3Params.AssetParams = testAPs
|
||||
|
||||
// pricefeed Markets
|
||||
testMs := pricefeedtypes.Markets{
|
||||
@ -139,7 +153,7 @@ func (suite *PermissionTestSuite) TestSubParamChangePermission_Allows() {
|
||||
{Subspace: cdptypes.ModuleName, Key: string(cdptypes.KeyDebtThreshold)},
|
||||
{Subspace: cdptypes.ModuleName, Key: string(cdptypes.KeyCollateralParams)},
|
||||
{Subspace: cdptypes.ModuleName, Key: string(cdptypes.KeyDebtParam)},
|
||||
{Subspace: bep3types.ModuleName, Key: string(bep3types.KeySupportedAssets)},
|
||||
{Subspace: bep3types.ModuleName, Key: string(bep3types.KeyAssetParams)},
|
||||
{Subspace: pricefeedtypes.ModuleName, Key: string(pricefeedtypes.KeyMarkets)},
|
||||
},
|
||||
AllowedCollateralParams: types.AllowedCollateralParams{
|
||||
@ -195,7 +209,7 @@ func (suite *PermissionTestSuite) TestSubParamChangePermission_Allows() {
|
||||
},
|
||||
{
|
||||
Subspace: bep3types.ModuleName,
|
||||
Key: string(bep3types.KeySupportedAssets),
|
||||
Key: string(bep3types.KeyAssetParams),
|
||||
Value: string(suite.cdc.MustMarshalJSON(testAPsUpdatedActive)),
|
||||
},
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
bep3types "github.com/kava-labs/kava/x/bep3/types"
|
||||
cdptypes "github.com/kava-labs/kava/x/cdp/types"
|
||||
pricefeedtypes "github.com/kava-labs/kava/x/pricefeed/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
)
|
||||
|
||||
// Avoid cluttering test cases with long function names
|
||||
@ -155,24 +156,43 @@ func (suite *PermissionsTestSuite) TestAllowedCollateralParams_Allows() {
|
||||
}
|
||||
|
||||
func (suite *PermissionsTestSuite) TestAllowedAssetParams_Allows() {
|
||||
deputyAddress := sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser1")))
|
||||
testAPs := bep3types.AssetParams{
|
||||
{
|
||||
Denom: "bnb",
|
||||
CoinID: 714,
|
||||
Limit: i(1000000000000),
|
||||
Active: true,
|
||||
bep3types.AssetParam{
|
||||
Denom: "btc",
|
||||
CoinID: 0,
|
||||
SupplyLimit: sdk.NewInt(100),
|
||||
Active: false,
|
||||
DeputyAddress: deputyAddress,
|
||||
FixedFee: sdk.NewInt(1000),
|
||||
MinSwapAmount: sdk.OneInt(),
|
||||
MaxSwapAmount: sdk.NewInt(1000000000000),
|
||||
MinBlockLock: bep3types.DefaultMinBlockLock,
|
||||
MaxBlockLock: bep3types.DefaultMaxBlockLock,
|
||||
},
|
||||
{
|
||||
Denom: "btc",
|
||||
CoinID: 0,
|
||||
Limit: i(1000000000000),
|
||||
Active: true,
|
||||
bep3types.AssetParam{
|
||||
Denom: "bnb",
|
||||
CoinID: 714,
|
||||
SupplyLimit: sdk.NewInt(350000000000000),
|
||||
Active: true,
|
||||
DeputyAddress: deputyAddress,
|
||||
FixedFee: sdk.NewInt(1000),
|
||||
MinSwapAmount: sdk.OneInt(),
|
||||
MaxSwapAmount: sdk.NewInt(1000000000000),
|
||||
MinBlockLock: bep3types.DefaultMinBlockLock,
|
||||
MaxBlockLock: bep3types.DefaultMaxBlockLock,
|
||||
},
|
||||
{
|
||||
Denom: "xrp",
|
||||
CoinID: 144,
|
||||
Limit: i(1000000000000),
|
||||
Active: true,
|
||||
bep3types.AssetParam{
|
||||
Denom: "xrp",
|
||||
CoinID: 414,
|
||||
SupplyLimit: sdk.NewInt(350000000000000),
|
||||
Active: true,
|
||||
DeputyAddress: deputyAddress,
|
||||
FixedFee: sdk.NewInt(1000),
|
||||
MinSwapAmount: sdk.OneInt(),
|
||||
MaxSwapAmount: sdk.NewInt(1000000000000),
|
||||
MinBlockLock: bep3types.DefaultMinBlockLock,
|
||||
MaxBlockLock: bep3types.DefaultMaxBlockLock,
|
||||
},
|
||||
}
|
||||
updatedTestAPs := make(bep3types.AssetParams, len(testAPs))
|
||||
@ -180,10 +200,10 @@ func (suite *PermissionsTestSuite) TestAllowedAssetParams_Allows() {
|
||||
updatedTestAPs[1] = testAPs[0]
|
||||
updatedTestAPs[2] = testAPs[2]
|
||||
|
||||
updatedTestAPs[0].Limit = i(1000) // btc
|
||||
updatedTestAPs[1].Active = false // bnb
|
||||
updatedTestAPs[2].Limit = i(1000) // xrp
|
||||
updatedTestAPs[2].Active = false // xrp
|
||||
updatedTestAPs[0].SupplyLimit = i(1000) // btc
|
||||
updatedTestAPs[1].Active = false // bnb
|
||||
updatedTestAPs[2].SupplyLimit = i(1000) // xrp
|
||||
updatedTestAPs[2].Active = false // xrp
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
@ -238,6 +258,7 @@ func (suite *PermissionsTestSuite) TestAllowedAssetParams_Allows() {
|
||||
{
|
||||
Denom: "bnb",
|
||||
Active: true,
|
||||
Limit: true,
|
||||
},
|
||||
{
|
||||
Denom: "btc",
|
||||
@ -575,20 +596,26 @@ func (suite *PermissionsTestSuite) TestAllowedDebtParam_Allows() {
|
||||
|
||||
func (suite *PermissionsTestSuite) TestAllowedAssetParam_Allows() {
|
||||
testAP := bep3types.AssetParam{
|
||||
Denom: "usdx",
|
||||
CoinID: 999,
|
||||
Limit: i(1000000000),
|
||||
Active: true,
|
||||
Denom: "usdx",
|
||||
CoinID: 999,
|
||||
SupplyLimit: sdk.NewInt(1000000000),
|
||||
Active: true,
|
||||
DeputyAddress: sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser1"))),
|
||||
FixedFee: sdk.NewInt(1000),
|
||||
MinSwapAmount: sdk.OneInt(),
|
||||
MaxSwapAmount: sdk.NewInt(1000000000000),
|
||||
MinBlockLock: bep3types.DefaultMinBlockLock,
|
||||
MaxBlockLock: bep3types.DefaultMaxBlockLock,
|
||||
}
|
||||
newCoinidAP := testAP
|
||||
newCoinidAP.CoinID = 0
|
||||
|
||||
newLimitAP := testAP
|
||||
newLimitAP.Limit = i(1000)
|
||||
newLimitAP.SupplyLimit = i(1000)
|
||||
|
||||
newCoinidAndLimitAP := testAP
|
||||
newCoinidAndLimitAP.CoinID = 0
|
||||
newCoinidAndLimitAP.Limit = i(1000)
|
||||
newCoinidAndLimitAP.SupplyLimit = i(1000)
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
|
@ -260,7 +260,7 @@ func (perm SubParamChangePermission) Allows(ctx sdk.Context, appCdc *codec.Codec
|
||||
var foundIncomingAPs bool
|
||||
var incomingAPs bep3types.AssetParams
|
||||
for _, change := range proposal.Changes {
|
||||
if !(change.Subspace == bep3types.ModuleName && change.Key == string(bep3types.KeySupportedAssets)) {
|
||||
if !(change.Subspace == bep3types.ModuleName && change.Key == string(bep3types.KeyAssetParams)) {
|
||||
continue
|
||||
}
|
||||
// note: in case of duplicates take the last value
|
||||
@ -277,7 +277,7 @@ func (perm SubParamChangePermission) Allows(ctx sdk.Context, appCdc *codec.Codec
|
||||
return false // not using a panic to help avoid begin blocker panics
|
||||
}
|
||||
var currentAPs bep3types.AssetParams
|
||||
subspace.Get(ctx, bep3types.KeySupportedAssets, ¤tAPs) // panics if something goes wrong
|
||||
subspace.Get(ctx, bep3types.KeyAssetParams, ¤tAPs) // panics if something goes wrong
|
||||
|
||||
// Check all the incoming changes in the CollateralParams are allowed
|
||||
assetParamsChangesAllowed := perm.AllowedAssetParams.Allows(currentAPs, incomingAPs)
|
||||
@ -473,9 +473,10 @@ type AllowedAssetParam struct {
|
||||
}
|
||||
|
||||
func (aap AllowedAssetParam) Allows(current, incoming bep3types.AssetParam) bool {
|
||||
|
||||
allowed := ((aap.Denom == current.Denom) && (aap.Denom == incoming.Denom)) && // require denoms to be all equal
|
||||
((current.CoinID == incoming.CoinID) || aap.CoinID) &&
|
||||
(current.Limit.Equal(incoming.Limit) || aap.Limit) &&
|
||||
(current.SupplyLimit.Equal(incoming.SupplyLimit) || aap.Limit) &&
|
||||
((current.Active == incoming.Active) || aap.Active)
|
||||
return allowed
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user