Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(evmutil): add allow list for evm-convertible sdk denoms #1590

Merged
merged 14 commits into from
May 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions app/ante/eip712_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
1 change: 1 addition & 0 deletions ci/env/kava-protonet/genesis.json
Original file line number Diff line number Diff line change
Expand Up @@ -2004,6 +2004,7 @@
"evmutil": {
"accounts": [],
"params": {
"allowed_native_denoms": [],
"enabled_conversion_pairs": [
{
"kava_erc20_address": "0xBb304f44b7EFD865361F2AD973d8ebA433893ABC",
Expand Down
23 changes: 23 additions & 0 deletions docs/core/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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. |



Expand Down
17 changes: 17 additions & 0 deletions proto/kava/evmutil/v1beta1/conversion_pair.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
7 changes: 7 additions & 0 deletions proto/kava/evmutil/v1beta1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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"
];
}
8 changes: 8 additions & 0 deletions x/evmutil/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
23 changes: 23 additions & 0 deletions x/evmutil/keeper/migrations.go
Original file line number Diff line number Diff line change
@@ -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)
}
2 changes: 1 addition & 1 deletion x/evmutil/keeper/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, &params)
k.paramSubspace.GetParamSetIfExists(ctx, &params)
return params
}

Expand Down
26 changes: 26 additions & 0 deletions x/evmutil/keeper/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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 changes: 23 additions & 0 deletions x/evmutil/migrations/v2/store.go
Original file line number Diff line number Diff line change
@@ -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 changes: 54 additions & 0 deletions x/evmutil/migrations/v2/store_test.go
Original file line number Diff line number Diff line change
@@ -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))
}
5 changes: 4 additions & 1 deletion x/evmutil/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
)

// ConsensusVersion defines the current module consensus version.
const ConsensusVersion = 1
const ConsensusVersion = 2

var (
_ module.AppModule = AppModule{}
Expand Down Expand Up @@ -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.
Expand Down
24 changes: 23 additions & 1 deletion x/evmutil/spec/02_state.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@ 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
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
Expand All @@ -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.
Expand Down
20 changes: 17 additions & 3 deletions x/evmutil/spec/05_params.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ order: 5

The evmutil module contains the following parameters:

| Key | Type | Example |
| ---------------------- | ---------------------- | ------------- |
| EnabledConversionPairs | array (ConversionPair) | [{see below}] |
| Key | Type | Example |
| ---------------------- | ------------------------------------ | ------------- |
| EnabledConversionPairs | array (ConversionPair) | [{see below}] |
| AllowedNativeDenoms | array (AllowedNativeCoinERC20Tokens) | [{see below}] |

Example parameters for `ConversionPair`:

Expand All @@ -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.
1 change: 1 addition & 0 deletions x/evmutil/testutil/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ func (suite *Suite) SetupTest() {
"erc20/usdc",
),
),
types.NewAllowedNativeCoinERC20Tokens(),
))

queryHelper := baseapp.NewQueryServerTestHelper(suite.Ctx, suite.App.InterfaceRegistry())
Expand Down
Loading