mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-11-10 10:05:18 +00:00
feat(evmutil): add allow list for evm-convertible sdk denoms (#1590)
* add proto for allowed sdk denoms -> evm conversion * add validation for AllowedNativeCoinERC20Token * add validation for AllowedNativeCoinERC20Tokens * add AllowedNativeDenoms into params & genesis * add evmutil Params.Validate() test * fix eip712 ante test * update changelog * update internal testnet genesis.json * update state & param specs updates to the sections describing functionality will be updated once that functionality actually exists... :) * update field decimal -> decimals field now matches erc20 spec * add validation decimals will cast to uint8 * add v2 store migration for evmutil * create & register evmutil migrations * adds migrator to evmutil's keeper * sets up Migrate1To2 migration * registers migration in module * updates GetParams to properly handle historic block queries * add unit test for GetParams with historic store
This commit is contained in:
parent
362e39abf6
commit
ff709d73e1
@ -36,6 +36,9 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## Features
|
||||
- (evmutil) [#1590] Add allow list param of sdk native denoms that can be transferred to evm
|
||||
|
||||
## [v0.23.0]
|
||||
|
||||
### Improvements
|
||||
@ -237,6 +240,7 @@ the [changelog](https://github.com/cosmos/cosmos-sdk/blob/v0.38.4/CHANGELOG.md).
|
||||
- [#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run
|
||||
large-scale simulations remotely using aws-batch
|
||||
|
||||
[#1590]: https://github.com/Kava-Labs/kava/pull/1590
|
||||
[#1568]: https://github.com/Kava-Labs/kava/pull/1568
|
||||
[#1567]: https://github.com/Kava-Labs/kava/pull/1567
|
||||
[#1566]: https://github.com/Kava-Labs/kava/pull/1566
|
||||
|
@ -335,15 +335,16 @@ func (suite *EIP712TestSuite) SetupTest() {
|
||||
suite.usdcEVMAddr = pair.GetAddress()
|
||||
|
||||
// Add a contract to evmutil conversion pair
|
||||
suite.evmutilKeeper.SetParams(suite.ctx, evmutiltypes.NewParams(
|
||||
evmutilParams := suite.evmutilKeeper.GetParams(suite.ctx)
|
||||
evmutilParams.EnabledConversionPairs =
|
||||
evmutiltypes.NewConversionPairs(
|
||||
evmutiltypes.NewConversionPair(
|
||||
// First contract evmutil module deploys
|
||||
evmutiltestutil.MustNewInternalEVMAddressFromString("0x15932E26f5BD4923d46a2b205191C4b5d5f43FE3"),
|
||||
"erc20/usdc",
|
||||
),
|
||||
),
|
||||
))
|
||||
)
|
||||
suite.evmutilKeeper.SetParams(suite.ctx, evmutilParams)
|
||||
|
||||
// allow msgs through evm eip712
|
||||
evmKeeper := suite.tApp.GetEvmKeeper()
|
||||
|
1
ci/env/kava-protonet/genesis.json
vendored
1
ci/env/kava-protonet/genesis.json
vendored
@ -2004,6 +2004,7 @@
|
||||
"evmutil": {
|
||||
"accounts": [],
|
||||
"params": {
|
||||
"allowed_native_denoms": [],
|
||||
"enabled_conversion_pairs": [
|
||||
{
|
||||
"kava_erc20_address": "0xBb304f44b7EFD865361F2AD973d8ebA433893ABC",
|
||||
|
@ -247,6 +247,7 @@
|
||||
- [Msg](#kava.earn.v1beta1.Msg)
|
||||
|
||||
- [kava/evmutil/v1beta1/conversion_pair.proto](#kava/evmutil/v1beta1/conversion_pair.proto)
|
||||
- [AllowedNativeCoinERC20Token](#kava.evmutil.v1beta1.AllowedNativeCoinERC20Token)
|
||||
- [ConversionPair](#kava.evmutil.v1beta1.ConversionPair)
|
||||
|
||||
- [kava/evmutil/v1beta1/genesis.proto](#kava/evmutil/v1beta1/genesis.proto)
|
||||
@ -3658,6 +3659,27 @@ Msg defines the earn Msg service.
|
||||
|
||||
|
||||
|
||||
<a name="kava.evmutil.v1beta1.AllowedNativeCoinERC20Token"></a>
|
||||
|
||||
### AllowedNativeCoinERC20Token
|
||||
AllowedNativeCoinERC20Token defines allowed sdk denom & metadata
|
||||
for evm token representations of sdk assets.
|
||||
NOTE: once evm token contracts are deployed, changes to metadata for a given
|
||||
sdk_denom will not change metadata of deployed contract.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `sdk_denom` | [string](#string) | | Denom of the sdk.Coin |
|
||||
| `name` | [string](#string) | | Name of ERC20 contract |
|
||||
| `symbol` | [string](#string) | | Symbol of ERC20 contract |
|
||||
| `decimals` | [uint32](#uint32) | | Number of decimals ERC20 contract is deployed with. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="kava.evmutil.v1beta1.ConversionPair"></a>
|
||||
|
||||
### ConversionPair
|
||||
@ -3732,6 +3754,7 @@ Params defines the evmutil module params
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `enabled_conversion_pairs` | [ConversionPair](#kava.evmutil.v1beta1.ConversionPair) | repeated | enabled_conversion_pairs defines the list of conversion pairs allowed to be converted between Kava ERC20 and sdk.Coin |
|
||||
| `allowed_native_denoms` | [AllowedNativeCoinERC20Token](#kava.evmutil.v1beta1.AllowedNativeCoinERC20Token) | repeated | allowed_native_denoms is a list of denom & erc20 token metadata pairs. if a denom is in the list, it is allowed to be converted to an erc20 in the evm. |
|
||||
|
||||
|
||||
|
||||
|
@ -21,3 +21,20 @@ message ConversionPair {
|
||||
// Denom of the corresponding sdk.Coin
|
||||
string denom = 2;
|
||||
}
|
||||
|
||||
// AllowedNativeCoinERC20Token defines allowed sdk denom & metadata
|
||||
// for evm token representations of sdk assets.
|
||||
// NOTE: once evm token contracts are deployed, changes to metadata for a given
|
||||
// sdk_denom will not change metadata of deployed contract.
|
||||
message AllowedNativeCoinERC20Token {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// Denom of the sdk.Coin
|
||||
string sdk_denom = 1;
|
||||
// Name of ERC20 contract
|
||||
string name = 2;
|
||||
// Symbol of ERC20 contract
|
||||
string symbol = 3;
|
||||
// Number of decimals ERC20 contract is deployed with.
|
||||
uint32 decimals = 4;
|
||||
}
|
||||
|
@ -44,4 +44,11 @@ message Params {
|
||||
(gogoproto.nullable) = false,
|
||||
(gogoproto.castrepeated) = "ConversionPairs"
|
||||
];
|
||||
|
||||
// allowed_native_denoms is a list of denom & erc20 token metadata pairs.
|
||||
// if a denom is in the list, it is allowed to be converted to an erc20 in the evm.
|
||||
repeated AllowedNativeCoinERC20Token allowed_native_denoms = 1 [
|
||||
(gogoproto.nullable) = false,
|
||||
(gogoproto.castrepeated) = "AllowedNativeCoinERC20Tokens"
|
||||
];
|
||||
}
|
||||
|
@ -79,6 +79,14 @@ func (s *genesisTestSuite) TestExportGenesis() {
|
||||
KavaERC20Address: testutil.MustNewInternalEVMAddressFromString("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2").Bytes(),
|
||||
Denom: "weth"},
|
||||
}
|
||||
params.AllowedNativeDenoms = []types.AllowedNativeCoinERC20Token{
|
||||
{
|
||||
SdkDenom: "hard",
|
||||
Name: "Kava EVM HARD",
|
||||
Symbol: "HARD",
|
||||
Decimals: 6,
|
||||
},
|
||||
}
|
||||
s.Keeper.SetParams(s.Ctx, params)
|
||||
gs := evmutil.ExportGenesis(s.Ctx, s.Keeper)
|
||||
s.Require().Equal(gs.Accounts, accounts)
|
||||
|
23
x/evmutil/keeper/migrations.go
Normal file
23
x/evmutil/keeper/migrations.go
Normal file
@ -0,0 +1,23 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
v2 "github.com/kava-labs/kava/x/evmutil/migrations/v2"
|
||||
)
|
||||
|
||||
// Migrator is a struct for handling in-place store migrations.
|
||||
type Migrator struct {
|
||||
keeper Keeper
|
||||
}
|
||||
|
||||
// NewMigrator returns a new Migrator.
|
||||
func NewMigrator(keeper Keeper) Migrator {
|
||||
return Migrator{
|
||||
keeper: keeper,
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate1to2 migrates from version 1 to 2.
|
||||
func (m Migrator) Migrate1to2(ctx sdk.Context) error {
|
||||
return v2.MigrateStore(ctx, m.keeper.paramSubspace)
|
||||
}
|
@ -11,7 +11,7 @@ import (
|
||||
|
||||
// GetParams returns the total set of evm parameters.
|
||||
func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
|
||||
k.paramSubspace.GetParamSet(ctx, ¶ms)
|
||||
k.paramSubspace.GetParamSetIfExists(ctx, ¶ms)
|
||||
return params
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,9 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/kava-labs/kava/x/evmutil/keeper"
|
||||
"github.com/kava-labs/kava/x/evmutil/testutil"
|
||||
"github.com/kava-labs/kava/x/evmutil/types"
|
||||
)
|
||||
@ -34,3 +37,26 @@ func (suite *ParamsTestSuite) TestEnabledConversionPair() {
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().Equal(expPair, actualPair)
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) TestHistoricParamsQuery() {
|
||||
// setup a params store that lacks allowed_native_denoms param (as was the case in v1)
|
||||
oldParamStore := suite.App.GetParamsKeeper().Subspace("test_subspace_for_evmutil")
|
||||
oldParamStore.WithKeyTable(types.ParamKeyTable())
|
||||
oldParamStore.Set(suite.Ctx, types.KeyEnabledConversionPairs, types.ConversionPairs{})
|
||||
|
||||
suite.True(oldParamStore.Has(suite.Ctx, types.KeyEnabledConversionPairs))
|
||||
suite.False(oldParamStore.Has(suite.Ctx, types.KeyAllowedNativeDenoms))
|
||||
|
||||
oldStateKeeper := keeper.NewKeeper(
|
||||
suite.App.AppCodec(),
|
||||
sdk.NewKVStoreKey(types.StoreKey),
|
||||
oldParamStore,
|
||||
suite.App.GetBankKeeper(),
|
||||
suite.App.GetAccountKeeper(),
|
||||
)
|
||||
|
||||
// prior to making GetParams() use GetParamSetIfExists, this would panic.
|
||||
suite.NotPanics(func() {
|
||||
_ = oldStateKeeper.GetParams(suite.Ctx)
|
||||
})
|
||||
}
|
||||
|
23
x/evmutil/migrations/v2/store.go
Normal file
23
x/evmutil/migrations/v2/store.go
Normal file
@ -0,0 +1,23 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
|
||||
"github.com/kava-labs/kava/x/evmutil/types"
|
||||
)
|
||||
|
||||
// MigrateStore performs in-place store migrations for consensus version 2
|
||||
// V2 adds the allowed_native_denoms param to parameters.
|
||||
func MigrateStore(ctx sdk.Context, paramstore paramtypes.Subspace) error {
|
||||
migrateParamsStore(ctx, paramstore)
|
||||
return nil
|
||||
}
|
||||
|
||||
// migrateParamsStore ensures the param key table exists and has the allowed_native_denoms property
|
||||
func migrateParamsStore(ctx sdk.Context, paramstore paramtypes.Subspace) {
|
||||
if !paramstore.HasKeyTable() {
|
||||
paramstore.WithKeyTable(types.ParamKeyTable())
|
||||
}
|
||||
paramstore.Set(ctx, types.KeyAllowedNativeDenoms, types.DefaultAllowedNativeDenoms)
|
||||
}
|
54
x/evmutil/migrations/v2/store_test.go
Normal file
54
x/evmutil/migrations/v2/store_test.go
Normal file
@ -0,0 +1,54 @@
|
||||
package v2_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
|
||||
v2evmutil "github.com/kava-labs/kava/x/evmutil/migrations/v2"
|
||||
"github.com/kava-labs/kava/x/evmutil/types"
|
||||
)
|
||||
|
||||
func TestStoreMigrationAddsKeyTableIncludingNewParam(t *testing.T) {
|
||||
encCfg := simapp.MakeTestEncodingConfig()
|
||||
evmutilKey := sdk.NewKVStoreKey(types.ModuleName)
|
||||
tEvmutilKey := sdk.NewTransientStoreKey("transient_test")
|
||||
ctx := testutil.DefaultContext(evmutilKey, tEvmutilKey)
|
||||
paramstore := paramtypes.NewSubspace(encCfg.Codec, encCfg.Amino, evmutilKey, tEvmutilKey, types.ModuleName)
|
||||
|
||||
// Check param doesn't exist before
|
||||
require.False(t, paramstore.Has(ctx, types.KeyAllowedNativeDenoms))
|
||||
|
||||
// Run migrations.
|
||||
err := v2evmutil.MigrateStore(ctx, paramstore)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Make sure the new params are set.
|
||||
require.True(t, paramstore.Has(ctx, types.KeyAllowedNativeDenoms))
|
||||
}
|
||||
|
||||
func TestStoreMigrationSetsNewParamOnExistingKeyTable(t *testing.T) {
|
||||
encCfg := simapp.MakeTestEncodingConfig()
|
||||
evmutilKey := sdk.NewKVStoreKey(types.ModuleName)
|
||||
tEvmutilKey := sdk.NewTransientStoreKey("transient_test")
|
||||
ctx := testutil.DefaultContext(evmutilKey, tEvmutilKey)
|
||||
paramstore := paramtypes.NewSubspace(encCfg.Codec, encCfg.Amino, evmutilKey, tEvmutilKey, types.ModuleName)
|
||||
paramstore.WithKeyTable(types.ParamKeyTable())
|
||||
|
||||
// expect it to have key table
|
||||
require.True(t, paramstore.HasKeyTable())
|
||||
// expect it to not have new param
|
||||
require.False(t, paramstore.Has(ctx, types.KeyAllowedNativeDenoms))
|
||||
|
||||
// Run migrations.
|
||||
err := v2evmutil.MigrateStore(ctx, paramstore)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Make sure the new params are set.
|
||||
require.True(t, paramstore.Has(ctx, types.KeyAllowedNativeDenoms))
|
||||
}
|
@ -21,7 +21,7 @@ import (
|
||||
)
|
||||
|
||||
// ConsensusVersion defines the current module consensus version.
|
||||
const ConsensusVersion = 1
|
||||
const ConsensusVersion = 2
|
||||
|
||||
var (
|
||||
_ module.AppModule = AppModule{}
|
||||
@ -127,6 +127,9 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
|
||||
func (am AppModule) RegisterServices(cfg module.Configurator) {
|
||||
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
|
||||
types.RegisterQueryServer(cfg.QueryServer(), keeper.NewQueryServerImpl(am.keeper))
|
||||
|
||||
m := keeper.NewMigrator(am.keeper)
|
||||
cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2)
|
||||
}
|
||||
|
||||
// RegisterInvariants registers evmutil module's invariants.
|
||||
|
@ -6,7 +6,7 @@ order: 2
|
||||
|
||||
## Parameters and Genesis State
|
||||
|
||||
`Parameters` define the list of conversion pairs allowed to be converted between Kava ERC20 tokens and sdk.Coins.
|
||||
`Parameters` define the list of conversion pairs allowed to be converted between Kava ERC20 tokens & sdk.Coins, and the list of native sdk.Coins that are allowed to be converted to ERC20s.
|
||||
|
||||
```protobuf
|
||||
// Params defines the evmutil module params
|
||||
@ -14,6 +14,10 @@ message Params {
|
||||
// enabled_conversion_pairs defines the list of conversion pairs allowed to be
|
||||
// converted between Kava ERC20 and sdk.Coin
|
||||
repeated ConversionPair enabled_conversion_pairs = 4;
|
||||
|
||||
// allowed_native_denoms is a list of denom & erc20 token metadata pairs.
|
||||
// if a denom is in the list, it is allowed to be converted to an erc20 in the evm.
|
||||
repeated AllowedNativeCoinERC20Token allowed_native_denoms = 1;
|
||||
}
|
||||
|
||||
// ConversionPair defines a Kava ERC20 address and corresponding denom that is
|
||||
@ -24,6 +28,24 @@ message ConversionPair {
|
||||
// Denom of the corresponding sdk.Coin
|
||||
string denom = 2;
|
||||
}
|
||||
|
||||
// AllowedNativeCoinERC20Token defines allowed sdk denom & metadata
|
||||
// for evm token representations of sdk assets.
|
||||
// NOTE: once evm token contracts are deployed, changes to metadata for a given
|
||||
// sdk_denom will not change metadata of deployed contract.
|
||||
message AllowedNativeCoinERC20Token {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// Denom of the sdk.Coin
|
||||
string sdk_denom = 1;
|
||||
// Name of ERC20 contract
|
||||
string name = 2;
|
||||
// Symbol of ERC20 contract
|
||||
string symbol = 3;
|
||||
// Number of decimals ERC20 contract is deployed with.
|
||||
uint32 decimal = 4;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
`GenesisState` defines the state that must be persisted when the blockchain stops/restarts in order for normal function of the evmutil module to resume.
|
||||
|
@ -7,8 +7,9 @@ order: 5
|
||||
The evmutil module contains the following parameters:
|
||||
|
||||
| Key | Type | Example |
|
||||
| ---------------------- | ---------------------- | ------------- |
|
||||
| ---------------------- | ------------------------------------ | ------------- |
|
||||
| EnabledConversionPairs | array (ConversionPair) | [{see below}] |
|
||||
| AllowedNativeDenoms | array (AllowedNativeCoinERC20Tokens) | [{see below}] |
|
||||
|
||||
Example parameters for `ConversionPair`:
|
||||
|
||||
@ -17,6 +18,19 @@ Example parameters for `ConversionPair`:
|
||||
| kava_erc20_Address | string | "0x43d8814fdfb9b8854422df13f1c66e34e4fa91fd" | ERC20 contract address |
|
||||
| denom | string | "erc20/chain/usdc" | sdk.Coin denom for the ERC20 token |
|
||||
|
||||
Example parameters for `AllowedNativeCoinERC20Token`:
|
||||
|
||||
| Key | Type | Example | Description |
|
||||
| --------- | ------ | ---------------------------------------------------------------------- | -------------------------------------------------- |
|
||||
| sdk_denom | string | "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2" | denom of the sdk.Coin |
|
||||
| name | string | "Kava-wrapped Atom" | name field of the erc20 token |
|
||||
| symbol | string | "kATOM" | symbol field of the erc20 token |
|
||||
| decimal | uint32 | 6 | decimal field of the erc20 token, for display only |
|
||||
|
||||
## EnabledConversionPairs
|
||||
|
||||
The enabled conversion pairs parameter is an array of ConversionPair entries mapping an erc20 address to a sdk.Coin denom. Only erc20 contract addresses that are in this list can be converted to sdk.Coin and vice versa.
|
||||
|
||||
## AllowedNativeDenoms
|
||||
|
||||
The allowed native denoms parameter is an array of AllowedNativeCoinERC20Token entries. They include the sdk.Coin denom and metadata for the ERC20 representation of the asset in Kava's EVM. Coins may only be transferred to the EVM if they are included in this list. A token in this list will have an ERC20 token contract deployed on first conversion. The token will be deployed with the metadata included in the AllowedNativeCoinERC20Token. Once deployed, changes to the metadata will not affect or change the deployed contract.
|
||||
|
@ -156,6 +156,7 @@ func (suite *Suite) SetupTest() {
|
||||
"erc20/usdc",
|
||||
),
|
||||
),
|
||||
types.NewAllowedNativeCoinERC20Tokens(),
|
||||
))
|
||||
|
||||
queryHelper := baseapp.NewQueryServerTestHelper(suite.Ctx, suite.App.InterfaceRegistry())
|
||||
|
@ -3,12 +3,18 @@ package types
|
||||
import (
|
||||
bytes "bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
///////////////
|
||||
// EVM -> SDK
|
||||
///////////////
|
||||
|
||||
// NewConversionPair returns a new ConversionPair.
|
||||
func NewConversionPair(address InternalEVMAddress, denom string) ConversionPair {
|
||||
return ConversionPair{
|
||||
@ -87,3 +93,87 @@ func validateConversionPairs(i interface{}) error {
|
||||
|
||||
return pairs.Validate()
|
||||
}
|
||||
|
||||
///////////////
|
||||
// SDK -> EVM
|
||||
///////////////
|
||||
|
||||
// NewAllowedNativeCoinERC20Token returns an AllowedNativeCoinERC20Token
|
||||
func NewAllowedNativeCoinERC20Token(
|
||||
sdkDenom, name, symbol string,
|
||||
decimal uint32,
|
||||
) AllowedNativeCoinERC20Token {
|
||||
return AllowedNativeCoinERC20Token{
|
||||
SdkDenom: sdkDenom,
|
||||
Name: name,
|
||||
Symbol: symbol,
|
||||
Decimals: decimal,
|
||||
}
|
||||
}
|
||||
|
||||
// Validate validates the fields of a single AllowedNativeCoinERC20Token
|
||||
func (token AllowedNativeCoinERC20Token) Validate() error {
|
||||
// disallow empty string fields
|
||||
if err := sdk.ValidateDenom(token.SdkDenom); err != nil {
|
||||
return fmt.Errorf("allowed native coin erc20 token's sdk denom is invalid: %v", err)
|
||||
}
|
||||
|
||||
if token.Name == "" {
|
||||
return errors.New("allowed native coin erc20 token's name cannot be empty")
|
||||
}
|
||||
|
||||
if token.Symbol == "" {
|
||||
return errors.New("allowed native coin erc20 token's symbol cannot be empty")
|
||||
}
|
||||
|
||||
// ensure decimals will properly cast to uint8 of erc20 spec
|
||||
if token.Decimals > math.MaxUint8 {
|
||||
return fmt.Errorf("allowed native coin erc20 token's decimals must be less than 256, found %d", token.Decimals)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AllowedNativeCoinERC20Tokens defines a slice of AllowedNativeCoinERC20Token
|
||||
type AllowedNativeCoinERC20Tokens []AllowedNativeCoinERC20Token
|
||||
|
||||
// NewAllowedNativeCoinERC20Tokens returns AllowedNativeCoinERC20Tokens from the provided values.
|
||||
func NewAllowedNativeCoinERC20Tokens(pairs ...AllowedNativeCoinERC20Token) AllowedNativeCoinERC20Tokens {
|
||||
return AllowedNativeCoinERC20Tokens(pairs)
|
||||
}
|
||||
|
||||
// Validate checks that all containing tokens are valid and that there are
|
||||
// no duplicate denoms or symbols.
|
||||
func (tokens AllowedNativeCoinERC20Tokens) Validate() error {
|
||||
// Disallow multiple instances of a single sdk_denom or evm symbol
|
||||
denoms := make(map[string]struct{}, len(tokens))
|
||||
symbols := make(map[string]struct{}, len(tokens))
|
||||
|
||||
for i, t := range tokens {
|
||||
if err := t.Validate(); err != nil {
|
||||
return fmt.Errorf("invalid token at index %d: %s", i, err)
|
||||
}
|
||||
|
||||
if _, found := denoms[t.SdkDenom]; found {
|
||||
return fmt.Errorf("found duplicate token with sdk denom %s", t.SdkDenom)
|
||||
}
|
||||
if _, found := symbols[t.Symbol]; found {
|
||||
return fmt.Errorf("found duplicate token with symbol %s", t.Symbol)
|
||||
}
|
||||
|
||||
denoms[t.SdkDenom] = struct{}{}
|
||||
symbols[t.Symbol] = struct{}{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateAllowedNativeCoinERC20Tokens validates an interface as AllowedNativeCoinERC20Tokens
|
||||
func validateAllowedNativeCoinERC20Tokens(i interface{}) error {
|
||||
pairs, ok := i.(AllowedNativeCoinERC20Tokens)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
return pairs.Validate()
|
||||
}
|
||||
|
@ -66,8 +66,57 @@ func (m *ConversionPair) XXX_DiscardUnknown() {
|
||||
|
||||
var xxx_messageInfo_ConversionPair proto.InternalMessageInfo
|
||||
|
||||
// AllowedNativeCoinERC20Token defines allowed sdk denom & metadata
|
||||
// for evm token representations of sdk assets.
|
||||
// NOTE: once evm token contracts are deployed, changes to metadata for a given
|
||||
// sdk_denom will not change metadata of deployed contract.
|
||||
type AllowedNativeCoinERC20Token struct {
|
||||
// Denom of the sdk.Coin
|
||||
SdkDenom string `protobuf:"bytes,1,opt,name=sdk_denom,json=sdkDenom,proto3" json:"sdk_denom,omitempty"`
|
||||
// Name of ERC20 contract
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
// Symbol of ERC20 contract
|
||||
Symbol string `protobuf:"bytes,3,opt,name=symbol,proto3" json:"symbol,omitempty"`
|
||||
// Number of decimals ERC20 contract is deployed with.
|
||||
Decimals uint32 `protobuf:"varint,4,opt,name=decimals,proto3" json:"decimals,omitempty"`
|
||||
}
|
||||
|
||||
func (m *AllowedNativeCoinERC20Token) Reset() { *m = AllowedNativeCoinERC20Token{} }
|
||||
func (m *AllowedNativeCoinERC20Token) String() string { return proto.CompactTextString(m) }
|
||||
func (*AllowedNativeCoinERC20Token) ProtoMessage() {}
|
||||
func (*AllowedNativeCoinERC20Token) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_e1396d08199817d0, []int{1}
|
||||
}
|
||||
func (m *AllowedNativeCoinERC20Token) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *AllowedNativeCoinERC20Token) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_AllowedNativeCoinERC20Token.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *AllowedNativeCoinERC20Token) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_AllowedNativeCoinERC20Token.Merge(m, src)
|
||||
}
|
||||
func (m *AllowedNativeCoinERC20Token) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *AllowedNativeCoinERC20Token) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_AllowedNativeCoinERC20Token.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_AllowedNativeCoinERC20Token proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ConversionPair)(nil), "kava.evmutil.v1beta1.ConversionPair")
|
||||
proto.RegisterType((*AllowedNativeCoinERC20Token)(nil), "kava.evmutil.v1beta1.AllowedNativeCoinERC20Token")
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -75,24 +124,30 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptor_e1396d08199817d0 = []byte{
|
||||
// 264 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0xca, 0x4e, 0x2c, 0x4b,
|
||||
0xd4, 0x4f, 0x2d, 0xcb, 0x2d, 0x2d, 0xc9, 0xcc, 0xd1, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34,
|
||||
0xd4, 0x4f, 0xce, 0xcf, 0x2b, 0x4b, 0x2d, 0x2a, 0xce, 0xcc, 0xcf, 0x8b, 0x2f, 0x48, 0xcc, 0x2c,
|
||||
0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x01, 0xa9, 0xd5, 0x83, 0xaa, 0xd5, 0x83, 0xaa,
|
||||
0x95, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, 0xd0, 0x07, 0xb1, 0x20, 0x6a, 0x95, 0x6a, 0xb8,
|
||||
0xf8, 0x9c, 0xe1, 0x86, 0x04, 0x24, 0x66, 0x16, 0x09, 0xf9, 0x71, 0x09, 0x81, 0xf4, 0xc7, 0xa7,
|
||||
0x16, 0x25, 0x1b, 0x19, 0xc4, 0x27, 0xa6, 0xa4, 0x14, 0xa5, 0x16, 0x17, 0x4b, 0x30, 0x2a, 0x30,
|
||||
0x6a, 0xf0, 0x38, 0x29, 0x3c, 0xba, 0x27, 0x2f, 0xe0, 0x9d, 0x58, 0x96, 0xe8, 0x1a, 0xe4, 0x6c,
|
||||
0x64, 0xe0, 0x08, 0x91, 0xfb, 0x75, 0x4f, 0x9e, 0xc3, 0x23, 0xb5, 0xc2, 0xa9, 0xb2, 0x24, 0xb5,
|
||||
0x38, 0x48, 0x00, 0xa4, 0xd7, 0x15, 0xa4, 0x15, 0x2a, 0x2b, 0x24, 0xc2, 0xc5, 0x9a, 0x92, 0x9a,
|
||||
0x97, 0x9f, 0x2b, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x19, 0x04, 0xe1, 0x58, 0xb1, 0x74, 0x2c, 0x90,
|
||||
0x67, 0x70, 0xf2, 0x7e, 0xf0, 0x50, 0x8e, 0x71, 0xc5, 0x23, 0x39, 0xc6, 0x13, 0x8f, 0xe4, 0x18,
|
||||
0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5,
|
||||
0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xd2, 0x4c, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce,
|
||||
0xcf, 0xd5, 0x07, 0x19, 0xad, 0x9b, 0x93, 0x98, 0x54, 0x0c, 0x66, 0xe9, 0x57, 0xc0, 0x83, 0xa3,
|
||||
0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0xec, 0x23, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x60, 0x36, 0x37, 0x7f, 0x2b, 0x01, 0x00, 0x00,
|
||||
// 355 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x3c, 0x91, 0xcf, 0x6a, 0xea, 0x40,
|
||||
0x18, 0xc5, 0x33, 0xf7, 0x7a, 0x45, 0x87, 0xdb, 0x22, 0x83, 0x94, 0xa0, 0x30, 0x06, 0x57, 0xb6,
|
||||
0xd0, 0x44, 0xed, 0xae, 0x3b, 0xb5, 0x42, 0x41, 0x90, 0x12, 0xba, 0xea, 0x26, 0x4c, 0x92, 0x0f,
|
||||
0x3b, 0xe4, 0xcf, 0x48, 0x26, 0xa6, 0x0a, 0x7d, 0x00, 0x97, 0x7d, 0x84, 0x2e, 0xfb, 0x28, 0x5d,
|
||||
0xba, 0xec, 0x4a, 0x6c, 0x7c, 0x8b, 0xae, 0x4a, 0xfe, 0xe0, 0xee, 0x9c, 0xf9, 0xce, 0xef, 0x30,
|
||||
0x33, 0x1f, 0xbe, 0xf2, 0x58, 0xc2, 0x0c, 0x48, 0x82, 0x55, 0xcc, 0x7d, 0x23, 0x19, 0xd8, 0x10,
|
||||
0xb3, 0x81, 0xe1, 0x88, 0x30, 0x81, 0x48, 0x72, 0x11, 0x5a, 0x4b, 0xc6, 0x23, 0x7d, 0x19, 0x89,
|
||||
0x58, 0x90, 0x66, 0x96, 0xd5, 0xcb, 0xac, 0x5e, 0x66, 0x5b, 0xcd, 0x85, 0x58, 0x88, 0x3c, 0x60,
|
||||
0x64, 0xaa, 0xc8, 0x76, 0x5f, 0xf1, 0xf9, 0xe4, 0x54, 0xf2, 0xc0, 0x78, 0x44, 0xe6, 0x98, 0x64,
|
||||
0xbc, 0x05, 0x91, 0x33, 0xec, 0x5b, 0xcc, 0x75, 0x23, 0x90, 0x52, 0x45, 0x1a, 0xea, 0xfd, 0x1f,
|
||||
0x6b, 0xe9, 0xbe, 0xd3, 0x98, 0xb1, 0x84, 0x4d, 0xcd, 0xc9, 0xb0, 0x3f, 0x2a, 0x66, 0x3f, 0xfb,
|
||||
0x4e, 0xed, 0x1e, 0xd6, 0xe3, 0x4d, 0x0c, 0xd2, 0x6c, 0x64, 0xec, 0x34, 0x43, 0xcb, 0x29, 0x69,
|
||||
0xe2, 0x7f, 0x2e, 0x84, 0x22, 0x50, 0xff, 0x68, 0xa8, 0x57, 0x37, 0x0b, 0x73, 0x5b, 0xd9, 0xbe,
|
||||
0x77, 0x94, 0xee, 0x16, 0xe1, 0xf6, 0xc8, 0xf7, 0xc5, 0x0b, 0xb8, 0x73, 0x16, 0xf3, 0x04, 0x26,
|
||||
0x82, 0x87, 0x79, 0xf7, 0xa3, 0xf0, 0x20, 0x24, 0x6d, 0x5c, 0x97, 0xae, 0x67, 0x15, 0x3c, 0xca,
|
||||
0xf9, 0x9a, 0x74, 0xbd, 0xbb, 0xcc, 0x13, 0x82, 0x2b, 0x21, 0x0b, 0xa0, 0xec, 0xcd, 0x35, 0xb9,
|
||||
0xc0, 0x55, 0xb9, 0x09, 0x6c, 0xe1, 0xab, 0x7f, 0xf3, 0xd3, 0xd2, 0x91, 0x16, 0xae, 0xb9, 0xe0,
|
||||
0xf0, 0x80, 0xf9, 0x52, 0xad, 0x68, 0xa8, 0x77, 0x66, 0x9e, 0x7c, 0x71, 0x95, 0xf1, 0xec, 0xf0,
|
||||
0x4d, 0xd1, 0x47, 0x4a, 0xd1, 0x67, 0x4a, 0xd1, 0x2e, 0xa5, 0xe8, 0x90, 0x52, 0xf4, 0x76, 0xa4,
|
||||
0xca, 0xee, 0x48, 0x95, 0xaf, 0x23, 0x55, 0x9e, 0x2e, 0x17, 0x3c, 0x7e, 0x5e, 0xd9, 0xba, 0x23,
|
||||
0x02, 0x23, 0x7b, 0xe5, 0xb5, 0xcf, 0x6c, 0x99, 0x2b, 0x63, 0x7d, 0xda, 0x4c, 0xbc, 0x59, 0x82,
|
||||
0xb4, 0xab, 0xf9, 0xe7, 0xde, 0xfc, 0x06, 0x00, 0x00, 0xff, 0xff, 0x49, 0x37, 0x2c, 0xa6, 0xb6,
|
||||
0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (this *ConversionPair) VerboseEqual(that interface{}) error {
|
||||
@ -155,6 +210,78 @@ func (this *ConversionPair) Equal(that interface{}) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (this *AllowedNativeCoinERC20Token) VerboseEqual(that interface{}) error {
|
||||
if that == nil {
|
||||
if this == nil {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("that == nil && this != nil")
|
||||
}
|
||||
|
||||
that1, ok := that.(*AllowedNativeCoinERC20Token)
|
||||
if !ok {
|
||||
that2, ok := that.(AllowedNativeCoinERC20Token)
|
||||
if ok {
|
||||
that1 = &that2
|
||||
} else {
|
||||
return fmt.Errorf("that is not of type *AllowedNativeCoinERC20Token")
|
||||
}
|
||||
}
|
||||
if that1 == nil {
|
||||
if this == nil {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("that is type *AllowedNativeCoinERC20Token but is nil && this != nil")
|
||||
} else if this == nil {
|
||||
return fmt.Errorf("that is type *AllowedNativeCoinERC20Token but is not nil && this == nil")
|
||||
}
|
||||
if this.SdkDenom != that1.SdkDenom {
|
||||
return fmt.Errorf("SdkDenom this(%v) Not Equal that(%v)", this.SdkDenom, that1.SdkDenom)
|
||||
}
|
||||
if this.Name != that1.Name {
|
||||
return fmt.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name)
|
||||
}
|
||||
if this.Symbol != that1.Symbol {
|
||||
return fmt.Errorf("Symbol this(%v) Not Equal that(%v)", this.Symbol, that1.Symbol)
|
||||
}
|
||||
if this.Decimals != that1.Decimals {
|
||||
return fmt.Errorf("Decimals this(%v) Not Equal that(%v)", this.Decimals, that1.Decimals)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *AllowedNativeCoinERC20Token) Equal(that interface{}) bool {
|
||||
if that == nil {
|
||||
return this == nil
|
||||
}
|
||||
|
||||
that1, ok := that.(*AllowedNativeCoinERC20Token)
|
||||
if !ok {
|
||||
that2, ok := that.(AllowedNativeCoinERC20Token)
|
||||
if ok {
|
||||
that1 = &that2
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if that1 == nil {
|
||||
return this == nil
|
||||
} else if this == nil {
|
||||
return false
|
||||
}
|
||||
if this.SdkDenom != that1.SdkDenom {
|
||||
return false
|
||||
}
|
||||
if this.Name != that1.Name {
|
||||
return false
|
||||
}
|
||||
if this.Symbol != that1.Symbol {
|
||||
return false
|
||||
}
|
||||
if this.Decimals != that1.Decimals {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (m *ConversionPair) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
@ -192,6 +319,55 @@ func (m *ConversionPair) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *AllowedNativeCoinERC20Token) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *AllowedNativeCoinERC20Token) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *AllowedNativeCoinERC20Token) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.Decimals != 0 {
|
||||
i = encodeVarintConversionPair(dAtA, i, uint64(m.Decimals))
|
||||
i--
|
||||
dAtA[i] = 0x20
|
||||
}
|
||||
if len(m.Symbol) > 0 {
|
||||
i -= len(m.Symbol)
|
||||
copy(dAtA[i:], m.Symbol)
|
||||
i = encodeVarintConversionPair(dAtA, i, uint64(len(m.Symbol)))
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
if len(m.Name) > 0 {
|
||||
i -= len(m.Name)
|
||||
copy(dAtA[i:], m.Name)
|
||||
i = encodeVarintConversionPair(dAtA, i, uint64(len(m.Name)))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
if len(m.SdkDenom) > 0 {
|
||||
i -= len(m.SdkDenom)
|
||||
copy(dAtA[i:], m.SdkDenom)
|
||||
i = encodeVarintConversionPair(dAtA, i, uint64(len(m.SdkDenom)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func encodeVarintConversionPair(dAtA []byte, offset int, v uint64) int {
|
||||
offset -= sovConversionPair(v)
|
||||
base := offset
|
||||
@ -220,6 +396,30 @@ func (m *ConversionPair) Size() (n int) {
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *AllowedNativeCoinERC20Token) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.SdkDenom)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovConversionPair(uint64(l))
|
||||
}
|
||||
l = len(m.Name)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovConversionPair(uint64(l))
|
||||
}
|
||||
l = len(m.Symbol)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovConversionPair(uint64(l))
|
||||
}
|
||||
if m.Decimals != 0 {
|
||||
n += 1 + sovConversionPair(uint64(m.Decimals))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovConversionPair(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
@ -342,6 +542,171 @@ func (m *ConversionPair) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *AllowedNativeCoinERC20Token) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowConversionPair
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: AllowedNativeCoinERC20Token: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: AllowedNativeCoinERC20Token: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field SdkDenom", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowConversionPair
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthConversionPair
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthConversionPair
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.SdkDenom = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowConversionPair
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthConversionPair
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthConversionPair
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Name = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Symbol", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowConversionPair
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthConversionPair
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthConversionPair
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Symbol = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Decimals", wireType)
|
||||
}
|
||||
m.Decimals = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowConversionPair
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Decimals |= uint32(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipConversionPair(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthConversionPair
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipConversionPair(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
|
@ -231,3 +231,125 @@ func TestConversionPairs_Validate(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllowedNativeCoinERC20Token_Validate(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
token types.AllowedNativeCoinERC20Token
|
||||
expErr string
|
||||
}{
|
||||
{
|
||||
name: "valid token",
|
||||
token: types.NewAllowedNativeCoinERC20Token("uatom", "Kava-wrapped ATOM", "kATOM", 6),
|
||||
expErr: "",
|
||||
},
|
||||
{
|
||||
name: "valid - highest allowed decimals",
|
||||
token: types.NewAllowedNativeCoinERC20Token("uatom", "Kava-wrapped ATOM", "kATOM", 255),
|
||||
expErr: "",
|
||||
},
|
||||
{
|
||||
name: "invalid - Empty SdkDenom",
|
||||
token: types.AllowedNativeCoinERC20Token{
|
||||
SdkDenom: "",
|
||||
Name: "Example Token",
|
||||
Symbol: "ETK",
|
||||
Decimals: 0,
|
||||
},
|
||||
expErr: "sdk denom is invalid",
|
||||
},
|
||||
{
|
||||
name: "invalid - Empty Name",
|
||||
token: types.AllowedNativeCoinERC20Token{
|
||||
SdkDenom: "example_denom",
|
||||
Name: "",
|
||||
Symbol: "ETK",
|
||||
Decimals: 6,
|
||||
},
|
||||
expErr: "name cannot be empty",
|
||||
},
|
||||
{
|
||||
name: "invalid - Empty Symbol",
|
||||
token: types.AllowedNativeCoinERC20Token{
|
||||
SdkDenom: "example_denom",
|
||||
Name: "Example Token",
|
||||
Symbol: "",
|
||||
Decimals: 6,
|
||||
},
|
||||
expErr: "symbol cannot be empty",
|
||||
},
|
||||
{
|
||||
name: "invalid - decimals higher than uint8",
|
||||
token: types.NewAllowedNativeCoinERC20Token("uatom", "Kava-wrapped ATOM", "kATOM", 256),
|
||||
expErr: "decimals must be less than 256",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := tc.token.Validate()
|
||||
if tc.expErr != "" {
|
||||
require.ErrorContains(t, err, tc.expErr, "Expected validation error")
|
||||
} else {
|
||||
require.NoError(t, err, "Expected no validation error")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllowedNativeCoinERC20Tokens_Validate(t *testing.T) {
|
||||
token1 := types.NewAllowedNativeCoinERC20Token("denom1", "Token 1", "TK1", 6)
|
||||
token2 := types.NewAllowedNativeCoinERC20Token("denom2", "Token 2", "TK2", 0)
|
||||
invalidToken := types.NewAllowedNativeCoinERC20Token("", "No SDK Denom Token", "TK3", 18)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
tokens types.AllowedNativeCoinERC20Tokens
|
||||
expErr string
|
||||
}{
|
||||
{
|
||||
name: "valid - no tokens",
|
||||
tokens: types.NewAllowedNativeCoinERC20Tokens(),
|
||||
expErr: "",
|
||||
},
|
||||
{
|
||||
name: "valid - one token",
|
||||
tokens: types.NewAllowedNativeCoinERC20Tokens(token1),
|
||||
expErr: "",
|
||||
},
|
||||
{
|
||||
name: "valid - multiple tokens",
|
||||
tokens: types.NewAllowedNativeCoinERC20Tokens(token1, token2),
|
||||
expErr: "",
|
||||
},
|
||||
{
|
||||
name: "invalid - contains invalid token",
|
||||
tokens: types.NewAllowedNativeCoinERC20Tokens(token1, token2, invalidToken),
|
||||
expErr: "invalid token at index 2",
|
||||
},
|
||||
{
|
||||
name: "invalid - duplicate denoms",
|
||||
tokens: types.NewAllowedNativeCoinERC20Tokens(token1, token2, token1),
|
||||
expErr: "found duplicate token with sdk denom denom1",
|
||||
},
|
||||
{
|
||||
name: "invalid - duplicate symbol",
|
||||
tokens: types.NewAllowedNativeCoinERC20Tokens(
|
||||
token1,
|
||||
types.NewAllowedNativeCoinERC20Token("diff", "Diff Denom, Same Symbol", "TK1", 6),
|
||||
),
|
||||
expErr: "found duplicate token with symbol TK1",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := tc.tokens.Validate()
|
||||
if tc.expErr != "" {
|
||||
require.ErrorContains(t, err, tc.expErr, "Expected validation error")
|
||||
} else {
|
||||
require.NoError(t, err, "Expected no validation error")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +111,9 @@ type Params struct {
|
||||
// enabled_conversion_pairs defines the list of conversion pairs allowed to be
|
||||
// converted between Kava ERC20 and sdk.Coin
|
||||
EnabledConversionPairs ConversionPairs `protobuf:"bytes,4,rep,name=enabled_conversion_pairs,json=enabledConversionPairs,proto3,castrepeated=ConversionPairs" json:"enabled_conversion_pairs"`
|
||||
// allowed_native_denoms is a list of denom & erc20 token metadata pairs.
|
||||
// if a denom is in the list, it is allowed to be converted to an erc20 in the evm.
|
||||
AllowedNativeDenoms AllowedNativeCoinERC20Tokens `protobuf:"bytes,1,rep,name=allowed_native_denoms,json=allowedNativeDenoms,proto3,castrepeated=AllowedNativeCoinERC20Tokens" json:"allowed_native_denoms"`
|
||||
}
|
||||
|
||||
func (m *Params) Reset() { *m = Params{} }
|
||||
@ -153,6 +156,13 @@ func (m *Params) GetEnabledConversionPairs() ConversionPairs {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Params) GetAllowedNativeDenoms() AllowedNativeCoinERC20Tokens {
|
||||
if m != nil {
|
||||
return m.AllowedNativeDenoms
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*GenesisState)(nil), "kava.evmutil.v1beta1.GenesisState")
|
||||
proto.RegisterType((*Account)(nil), "kava.evmutil.v1beta1.Account")
|
||||
@ -164,35 +174,38 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptor_d916ab97b8e628c2 = []byte{
|
||||
// 434 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x41, 0x8b, 0xd3, 0x40,
|
||||
0x14, 0xc7, 0x33, 0x5a, 0x5a, 0x9d, 0x5d, 0x10, 0xe2, 0xa2, 0x71, 0xd1, 0xc9, 0x52, 0x44, 0xaa,
|
||||
0x90, 0x84, 0x5d, 0x6f, 0x45, 0x90, 0xc6, 0x83, 0x16, 0x2f, 0x25, 0x82, 0x07, 0x2f, 0x65, 0x92,
|
||||
0x0c, 0x31, 0x34, 0x99, 0x09, 0x99, 0x69, 0xb4, 0x47, 0x6f, 0x1e, 0xf5, 0x1b, 0x78, 0x14, 0xcf,
|
||||
0xfd, 0x10, 0x05, 0x2f, 0xa5, 0x27, 0xf1, 0x50, 0x6b, 0xfa, 0x2d, 0x3c, 0x49, 0x32, 0xd3, 0xa2,
|
||||
0x25, 0x87, 0x3d, 0x65, 0xf2, 0xe7, 0xff, 0x7f, 0xef, 0xf7, 0xde, 0x0c, 0xec, 0x4e, 0x70, 0x81,
|
||||
0x1d, 0x52, 0xa4, 0x53, 0x11, 0x27, 0x4e, 0x71, 0xee, 0x13, 0x81, 0xcf, 0x9d, 0x88, 0x50, 0xc2,
|
||||
0x63, 0x6e, 0x67, 0x39, 0x13, 0x4c, 0x3f, 0xa9, 0x3c, 0xb6, 0xf2, 0xd8, 0xca, 0x73, 0x7a, 0x27,
|
||||
0x60, 0x3c, 0x65, 0x7c, 0x5c, 0x7b, 0x1c, 0xf9, 0x23, 0x03, 0xa7, 0x27, 0x11, 0x8b, 0x98, 0xd4,
|
||||
0xab, 0x93, 0x52, 0x1f, 0x35, 0xb6, 0x0a, 0x18, 0x2d, 0x48, 0xce, 0x63, 0x46, 0xc7, 0x19, 0x8e,
|
||||
0x73, 0xe9, 0xed, 0x7e, 0x06, 0xf0, 0xf8, 0xb9, 0x84, 0x78, 0x25, 0xb0, 0x20, 0xfa, 0x53, 0x78,
|
||||
0x0d, 0x07, 0x01, 0x9b, 0x52, 0xc1, 0x0d, 0x70, 0x76, 0xb5, 0x77, 0x74, 0x71, 0xcf, 0x6e, 0xc2,
|
||||
0xb2, 0x07, 0xd2, 0xe5, 0xb6, 0x16, 0x6b, 0x53, 0xf3, 0xf6, 0x21, 0xbd, 0x0f, 0xdb, 0x19, 0xce,
|
||||
0x71, 0xca, 0x8d, 0x2b, 0x67, 0xa0, 0x77, 0x74, 0x71, 0xb7, 0x39, 0x3e, 0xaa, 0x3d, 0x2a, 0xad,
|
||||
0x12, 0xfd, 0xd6, 0xc7, 0x2f, 0xa6, 0xd6, 0xfd, 0x0e, 0x60, 0x47, 0x55, 0xd7, 0x7d, 0xd8, 0xc1,
|
||||
0x61, 0x98, 0x13, 0x5e, 0xd1, 0x80, 0xde, 0xb1, 0xfb, 0xe2, 0xcf, 0xda, 0xb4, 0xa2, 0x58, 0xbc,
|
||||
0x9d, 0xfa, 0x76, 0xc0, 0x52, 0xb5, 0x0f, 0xf5, 0xb1, 0x78, 0x38, 0x71, 0xc4, 0x2c, 0x23, 0xbc,
|
||||
0xc2, 0x1b, 0xc8, 0xe0, 0x6a, 0x6e, 0xdd, 0x54, 0x5b, 0x53, 0x8a, 0x3b, 0x13, 0x84, 0x7b, 0xbb,
|
||||
0xc2, 0xfa, 0x6b, 0xd8, 0xf1, 0x71, 0x82, 0x69, 0x40, 0x6a, 0xe4, 0xeb, 0xee, 0x93, 0x0a, 0xea,
|
||||
0xe7, 0xda, 0x7c, 0x70, 0x89, 0x3e, 0x43, 0x2a, 0x56, 0x73, 0x0b, 0xaa, 0x06, 0x43, 0x2a, 0xbc,
|
||||
0x5d, 0x31, 0x35, 0xcd, 0x07, 0x00, 0xdb, 0x72, 0x58, 0xfd, 0x1d, 0x34, 0x08, 0xc5, 0x7e, 0x42,
|
||||
0xc2, 0xf1, 0xc1, 0x6d, 0x70, 0xa3, 0x55, 0xef, 0xfa, 0x7e, 0xf3, 0xb2, 0x9e, 0xed, 0xdd, 0x23,
|
||||
0x1c, 0xe7, 0xee, 0xed, 0x8a, 0xef, 0xdb, 0x2f, 0xf3, 0xc6, 0xff, 0x3a, 0xf7, 0x6e, 0xa9, 0xf2,
|
||||
0x07, 0xba, 0xfb, 0x72, 0xf3, 0x1b, 0x81, 0xaf, 0x25, 0x02, 0x8b, 0x12, 0x81, 0x65, 0x89, 0xc0,
|
||||
0xa6, 0x44, 0xe0, 0xd3, 0x16, 0x69, 0xcb, 0x2d, 0xd2, 0x7e, 0x6c, 0x91, 0xf6, 0xe6, 0xe1, 0x3f,
|
||||
0xa3, 0x56, 0x08, 0x56, 0x82, 0x7d, 0x5e, 0x9f, 0x9c, 0xf7, 0xfb, 0xa7, 0x54, 0x4f, 0xec, 0xb7,
|
||||
0xeb, 0x97, 0xf3, 0xf8, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x32, 0x69, 0x99, 0x1c, 0xd2, 0x02,
|
||||
0x00, 0x00,
|
||||
// 492 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x41, 0x6b, 0xd4, 0x40,
|
||||
0x14, 0xce, 0xd4, 0x65, 0x57, 0xa7, 0x05, 0x21, 0xad, 0xba, 0x96, 0x9a, 0x94, 0xa5, 0xc8, 0x2a,
|
||||
0x24, 0x71, 0xd7, 0x5b, 0x11, 0xa4, 0x59, 0x45, 0x8b, 0x20, 0x25, 0x8a, 0x07, 0x2f, 0xe1, 0x25,
|
||||
0x19, 0xd6, 0xb0, 0xc9, 0xcc, 0x92, 0x99, 0x4d, 0xed, 0x3f, 0x10, 0x3c, 0xa8, 0xff, 0xc0, 0xa3,
|
||||
0x78, 0xee, 0x8f, 0x28, 0x78, 0x29, 0x3d, 0x89, 0x87, 0xb5, 0xee, 0xfe, 0x0b, 0x4f, 0x92, 0x99,
|
||||
0xd9, 0xa5, 0x96, 0x55, 0x7a, 0xca, 0xe4, 0x9b, 0xef, 0x7b, 0xef, 0x9b, 0xef, 0x3d, 0xdc, 0x1a,
|
||||
0x40, 0x09, 0x1e, 0x29, 0xf3, 0x91, 0x48, 0x33, 0xaf, 0xec, 0x44, 0x44, 0x40, 0xc7, 0xeb, 0x13,
|
||||
0x4a, 0x78, 0xca, 0xdd, 0x61, 0xc1, 0x04, 0x33, 0xd7, 0x2a, 0x8e, 0xab, 0x39, 0xae, 0xe6, 0xac,
|
||||
0xdf, 0x8c, 0x19, 0xcf, 0x19, 0x0f, 0x25, 0xc7, 0x53, 0x3f, 0x4a, 0xb0, 0xbe, 0xd6, 0x67, 0x7d,
|
||||
0xa6, 0xf0, 0xea, 0xa4, 0xd1, 0xbb, 0x0b, 0x5b, 0xc5, 0x8c, 0x96, 0xa4, 0xe0, 0x29, 0xa3, 0xe1,
|
||||
0x10, 0xd2, 0x42, 0x71, 0x5b, 0x9f, 0x10, 0x5e, 0x79, 0xa2, 0x4c, 0xbc, 0x10, 0x20, 0x88, 0xf9,
|
||||
0x10, 0x5f, 0x86, 0x38, 0x66, 0x23, 0x2a, 0x78, 0x13, 0x6d, 0x5e, 0x6a, 0x2f, 0x77, 0x6f, 0xb9,
|
||||
0x8b, 0x6c, 0xb9, 0x3b, 0x8a, 0xe5, 0xd7, 0x8e, 0xc6, 0xb6, 0x11, 0xcc, 0x45, 0xe6, 0x36, 0xae,
|
||||
0x0f, 0xa1, 0x80, 0x9c, 0x37, 0x97, 0x36, 0x51, 0x7b, 0xb9, 0xbb, 0xb1, 0x58, 0xbe, 0x27, 0x39,
|
||||
0x5a, 0xad, 0x15, 0xdb, 0xb5, 0x77, 0x9f, 0x6d, 0xa3, 0xf5, 0x0d, 0xe1, 0x86, 0xae, 0x6e, 0x46,
|
||||
0xb8, 0x01, 0x49, 0x52, 0x10, 0x5e, 0xb9, 0x41, 0xed, 0x15, 0xff, 0xe9, 0xef, 0xb1, 0xed, 0xf4,
|
||||
0x53, 0xf1, 0x66, 0x14, 0xb9, 0x31, 0xcb, 0x75, 0x1e, 0xfa, 0xe3, 0xf0, 0x64, 0xe0, 0x89, 0x83,
|
||||
0x21, 0xe1, 0x95, 0xbd, 0x1d, 0x25, 0x3c, 0x39, 0x74, 0x56, 0x75, 0x6a, 0x1a, 0xf1, 0x0f, 0x04,
|
||||
0xe1, 0xc1, 0xac, 0xb0, 0xf9, 0x0a, 0x37, 0x22, 0xc8, 0x80, 0xc6, 0x44, 0x5a, 0xbe, 0xe2, 0x3f,
|
||||
0xa8, 0x4c, 0xfd, 0x18, 0xdb, 0xb7, 0x2f, 0xd0, 0x67, 0x97, 0x8a, 0x93, 0x43, 0x07, 0xeb, 0x06,
|
||||
0xbb, 0x54, 0x04, 0xb3, 0x62, 0xfa, 0x35, 0x1f, 0x96, 0x70, 0x5d, 0x3d, 0xd6, 0xdc, 0xc7, 0x4d,
|
||||
0x42, 0x21, 0xca, 0x48, 0x12, 0x9e, 0x9b, 0x06, 0x6f, 0xd6, 0x64, 0xd6, 0x5b, 0x8b, 0xc3, 0xea,
|
||||
0xcd, 0xd9, 0x7b, 0x90, 0x16, 0xfe, 0x8d, 0xca, 0xdf, 0xd7, 0x9f, 0xf6, 0xd5, 0xbf, 0x71, 0x1e,
|
||||
0x5c, 0xd7, 0xe5, 0xcf, 0xe1, 0xe6, 0x7b, 0x84, 0xaf, 0x41, 0x96, 0xb1, 0x7d, 0x92, 0x84, 0x14,
|
||||
0x44, 0x5a, 0x92, 0x30, 0x21, 0x94, 0xe5, 0xb3, 0x11, 0x77, 0xfe, 0x31, 0x62, 0x25, 0x79, 0x2e,
|
||||
0x15, 0x3d, 0x96, 0xd2, 0xc7, 0x41, 0xaf, 0x7b, 0xef, 0x25, 0x1b, 0x10, 0xea, 0x6f, 0x69, 0x0f,
|
||||
0x1b, 0xff, 0x21, 0xf1, 0x60, 0x15, 0xce, 0xde, 0x3e, 0x92, 0x3d, 0xfd, 0x67, 0xa7, 0xbf, 0x2c,
|
||||
0xf4, 0x65, 0x62, 0xa1, 0xa3, 0x89, 0x85, 0x8e, 0x27, 0x16, 0x3a, 0x9d, 0x58, 0xe8, 0xe3, 0xd4,
|
||||
0x32, 0x8e, 0xa7, 0x96, 0xf1, 0x7d, 0x6a, 0x19, 0xaf, 0xef, 0x9c, 0x09, 0xbe, 0x72, 0xe6, 0x64,
|
||||
0x10, 0x71, 0x79, 0xf2, 0xde, 0xce, 0x17, 0x5b, 0xe6, 0x1f, 0xd5, 0xe5, 0x1e, 0xdf, 0xff, 0x13,
|
||||
0x00, 0x00, 0xff, 0xff, 0xa3, 0x52, 0xb0, 0x81, 0x60, 0x03, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (this *GenesisState) VerboseEqual(that interface{}) error {
|
||||
@ -358,6 +371,14 @@ func (this *Params) VerboseEqual(that interface{}) error {
|
||||
return fmt.Errorf("EnabledConversionPairs this[%v](%v) Not Equal that[%v](%v)", i, this.EnabledConversionPairs[i], i, that1.EnabledConversionPairs[i])
|
||||
}
|
||||
}
|
||||
if len(this.AllowedNativeDenoms) != len(that1.AllowedNativeDenoms) {
|
||||
return fmt.Errorf("AllowedNativeDenoms this(%v) Not Equal that(%v)", len(this.AllowedNativeDenoms), len(that1.AllowedNativeDenoms))
|
||||
}
|
||||
for i := range this.AllowedNativeDenoms {
|
||||
if !this.AllowedNativeDenoms[i].Equal(&that1.AllowedNativeDenoms[i]) {
|
||||
return fmt.Errorf("AllowedNativeDenoms this[%v](%v) Not Equal that[%v](%v)", i, this.AllowedNativeDenoms[i], i, that1.AllowedNativeDenoms[i])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *Params) Equal(that interface{}) bool {
|
||||
@ -387,6 +408,14 @@ func (this *Params) Equal(that interface{}) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(this.AllowedNativeDenoms) != len(that1.AllowedNativeDenoms) {
|
||||
return false
|
||||
}
|
||||
for i := range this.AllowedNativeDenoms {
|
||||
if !this.AllowedNativeDenoms[i].Equal(&that1.AllowedNativeDenoms[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
|
||||
@ -510,6 +539,20 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
dAtA[i] = 0x22
|
||||
}
|
||||
}
|
||||
if len(m.AllowedNativeDenoms) > 0 {
|
||||
for iNdEx := len(m.AllowedNativeDenoms) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.AllowedNativeDenoms[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
@ -562,6 +605,12 @@ func (m *Params) Size() (n int) {
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.AllowedNativeDenoms) > 0 {
|
||||
for _, e := range m.AllowedNativeDenoms {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
if len(m.EnabledConversionPairs) > 0 {
|
||||
for _, e := range m.EnabledConversionPairs {
|
||||
l = e.Size()
|
||||
@ -841,6 +890,40 @@ func (m *Params) Unmarshal(dAtA []byte) error {
|
||||
return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field AllowedNativeDenoms", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.AllowedNativeDenoms = append(m.AllowedNativeDenoms, AllowedNativeCoinERC20Token{})
|
||||
if err := m.AllowedNativeDenoms[len(m.AllowedNativeDenoms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field EnabledConversionPairs", wireType)
|
||||
|
@ -47,9 +47,12 @@ func TestGenesisState_Validate(t *testing.T) {
|
||||
{Address: addrs[0], Balance: sdkmath.NewInt(100)},
|
||||
{Address: addrs[1], Balance: sdkmath.NewInt(150)},
|
||||
},
|
||||
params: types.NewParams(types.NewConversionPairs(
|
||||
params: types.NewParams(
|
||||
types.NewConversionPairs(
|
||||
types.NewConversionPair(types.NewInternalEVMAddress(common.HexToAddress("0xinvalidaddress")), "weth"),
|
||||
)),
|
||||
),
|
||||
types.NewAllowedNativeCoinERC20Tokens(),
|
||||
),
|
||||
success: false,
|
||||
},
|
||||
{
|
||||
|
@ -8,6 +8,8 @@ import (
|
||||
var (
|
||||
KeyEnabledConversionPairs = []byte("EnabledConversionPairs")
|
||||
DefaultConversionPairs = ConversionPairs{}
|
||||
KeyAllowedNativeDenoms = []byte("AllowedNativeDenoms")
|
||||
DefaultAllowedNativeDenoms = AllowedNativeCoinERC20Tokens{}
|
||||
)
|
||||
|
||||
// ParamKeyTable for evmutil module.
|
||||
@ -20,15 +22,18 @@ func ParamKeyTable() paramtypes.KeyTable {
|
||||
func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
|
||||
return paramtypes.ParamSetPairs{
|
||||
paramtypes.NewParamSetPair(KeyEnabledConversionPairs, &p.EnabledConversionPairs, validateConversionPairs),
|
||||
paramtypes.NewParamSetPair(KeyAllowedNativeDenoms, &p.AllowedNativeDenoms, validateAllowedNativeCoinERC20Tokens),
|
||||
}
|
||||
}
|
||||
|
||||
// NewParams returns new evmutil module Params.
|
||||
func NewParams(
|
||||
conversionPairs ConversionPairs,
|
||||
allowedNativeDenoms AllowedNativeCoinERC20Tokens,
|
||||
) Params {
|
||||
return Params{
|
||||
EnabledConversionPairs: conversionPairs,
|
||||
AllowedNativeDenoms: allowedNativeDenoms,
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,13 +41,17 @@ func NewParams(
|
||||
func DefaultParams() Params {
|
||||
return NewParams(
|
||||
DefaultConversionPairs,
|
||||
DefaultAllowedNativeDenoms,
|
||||
)
|
||||
}
|
||||
|
||||
// Validate returns an error if the Parmas is invalid.
|
||||
// Validate returns an error if the Params is invalid.
|
||||
func (p *Params) Validate() error {
|
||||
if err := p.EnabledConversionPairs.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.AllowedNativeDenoms.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -34,9 +34,13 @@ func (suite *ParamsTestSuite) TestMarshalYAML() {
|
||||
"usdc",
|
||||
),
|
||||
)
|
||||
allowedNativeDenoms := types.NewAllowedNativeCoinERC20Tokens(
|
||||
types.NewAllowedNativeCoinERC20Token("denom", "Sdk Denom!", "DENOM", 6),
|
||||
)
|
||||
|
||||
p := types.NewParams(
|
||||
conversionPairs,
|
||||
allowedNativeDenoms,
|
||||
)
|
||||
|
||||
data, err := yaml.Marshal(p)
|
||||
@ -47,6 +51,8 @@ func (suite *ParamsTestSuite) TestMarshalYAML() {
|
||||
suite.Require().NoError(err)
|
||||
_, ok := params["enabled_conversion_pairs"]
|
||||
suite.Require().True(ok, "enabled_conversion_pairs should exist in yaml")
|
||||
_, ok = params["allowed_native_denoms"]
|
||||
suite.Require().True(ok, "allowed_native_denoms should exist in yaml")
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) TestParamSetPairs_EnabledConversionPairs() {
|
||||
@ -70,6 +76,90 @@ func (suite *ParamsTestSuite) TestParamSetPairs_EnabledConversionPairs() {
|
||||
suite.Require().EqualError(paramSetPair.ValidatorFn(struct{}{}), "invalid parameter type: struct {}")
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) TestParamSetPairs_AllowedNativeDenoms() {
|
||||
suite.Require().Equal([]byte("AllowedNativeDenoms"), types.KeyAllowedNativeDenoms)
|
||||
defaultParams := types.DefaultParams()
|
||||
|
||||
var paramSetPair *paramstypes.ParamSetPair
|
||||
for _, pair := range defaultParams.ParamSetPairs() {
|
||||
if bytes.Equal(pair.Key, types.KeyAllowedNativeDenoms) {
|
||||
paramSetPair = &pair
|
||||
break
|
||||
}
|
||||
}
|
||||
suite.Require().NotNil(paramSetPair)
|
||||
|
||||
pairs, ok := paramSetPair.Value.(*types.AllowedNativeCoinERC20Tokens)
|
||||
suite.Require().True(ok)
|
||||
suite.Require().Equal(pairs, &defaultParams.AllowedNativeDenoms)
|
||||
|
||||
suite.Require().Nil(paramSetPair.ValidatorFn(*pairs))
|
||||
suite.Require().EqualError(paramSetPair.ValidatorFn(struct{}{}), "invalid parameter type: struct {}")
|
||||
}
|
||||
|
||||
func (suite *ParamsTestSuite) TestParams_Validate() {
|
||||
validConversionPairs := types.NewConversionPairs(
|
||||
types.NewConversionPair(
|
||||
testutil.MustNewInternalEVMAddressFromString("0x0000000000000000000000000000000000000001"),
|
||||
"usdc",
|
||||
),
|
||||
)
|
||||
invalidConversionPairs := types.NewConversionPairs(
|
||||
types.NewConversionPair(
|
||||
testutil.MustNewInternalEVMAddressFromString("0x000000000000000000000000000000000000000A"),
|
||||
"kava",
|
||||
),
|
||||
types.NewConversionPair(
|
||||
testutil.MustNewInternalEVMAddressFromString("0x000000000000000000000000000000000000000B"),
|
||||
"kava", // duplicate denom!
|
||||
),
|
||||
)
|
||||
validAllowedNativeDenoms := types.NewAllowedNativeCoinERC20Tokens(
|
||||
types.NewAllowedNativeCoinERC20Token("hard", "EVM Hard", "HARD", 6),
|
||||
)
|
||||
invalidAllowedNativeDenoms := types.NewAllowedNativeCoinERC20Tokens(
|
||||
types.NewAllowedNativeCoinERC20Token("", "Invalid Token", "NOPE", 0), // empty sdk denom
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
params types.Params
|
||||
expErr string
|
||||
}{
|
||||
{
|
||||
name: "valid - empty",
|
||||
params: types.NewParams(types.NewConversionPairs(), types.NewAllowedNativeCoinERC20Tokens()),
|
||||
expErr: "",
|
||||
},
|
||||
{
|
||||
name: "valid - with data",
|
||||
params: types.NewParams(validConversionPairs, validAllowedNativeDenoms),
|
||||
expErr: "",
|
||||
},
|
||||
{
|
||||
name: "invalid - invalid conversion pair",
|
||||
params: types.NewParams(invalidConversionPairs, validAllowedNativeDenoms),
|
||||
expErr: "found duplicate",
|
||||
},
|
||||
{
|
||||
name: "invalid - invalid allowed native denoms",
|
||||
params: types.NewParams(validConversionPairs, invalidAllowedNativeDenoms),
|
||||
expErr: "invalid token",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
err := tc.params.Validate()
|
||||
if tc.expErr != "" {
|
||||
suite.ErrorContains(err, tc.expErr, "Expected validation error")
|
||||
} else {
|
||||
suite.NoError(err, "Expected no validation error")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParamsTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(ParamsTestSuite))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user