From e855c8f1901a6954dec97748baabd7f98b5e02bc Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Tue, 18 Jun 2024 23:30:35 -0400 Subject: [PATCH 01/23] basic whitelist logic --- proto/osmosis/tokenfactory/params.proto | 39 ++ .../tokenfactory/v1beta1/genesis.proto | 2 +- .../osmosis/tokenfactory/v1beta1/params.proto | 2 +- .../osmosis/tokenfactory/v1beta1/query.proto | 2 +- proto/osmosis/tokenfactory/v1beta1/tx.proto | 2 +- wasmbinding/test/custom_message_test.go | 1 + wasmbinding/test/custom_query_test.go | 1 + x/tokenfactory/keeper/before_send.go | 5 + x/tokenfactory/keeper/before_send_test.go | 18 + x/tokenfactory/keeper/keeper_test.go | 1 + x/tokenfactory/keeper/params.go | 21 + x/tokenfactory/types/expected_keepers.go | 2 + x/tokenfactory/types/genesis.pb.go | 41 +- x/tokenfactory/types/params.go | 33 +- x/tokenfactory/types/params.pb.go | 338 ++++++++++++-- x/tokenfactory/types/query.pb.go | 88 ++-- x/tokenfactory/types/tx.go | 6 +- x/tokenfactory/types/tx.pb.go | 134 +++--- x/tokenfactory/types/v1beta1/params.pb.go | 442 ++++++++++++++++++ 19 files changed, 1002 insertions(+), 176 deletions(-) create mode 100644 proto/osmosis/tokenfactory/params.proto create mode 100644 x/tokenfactory/types/v1beta1/params.pb.go diff --git a/proto/osmosis/tokenfactory/params.proto b/proto/osmosis/tokenfactory/params.proto new file mode 100644 index 000000000..604da3956 --- /dev/null +++ b/proto/osmosis/tokenfactory/params.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package osmosis.tokenfactory; + +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/neutron-org/neutron/v4/x/tokenfactory/types"; + +message HookWhitelist { + uint64 code_id = 1 [(gogoproto.customname) = "CodeID"]; + string denom_creator = 2; +} + +// Params defines the parameters for the tokenfactory module. +message Params { + // DenomCreationFee defines the fee to be charged on the creation of a new + // denom. The fee is drawn from the MsgCreateDenom's sender account, and + // transferred to the community pool. + repeated cosmos.base.v1beta1.Coin denom_creation_fee = 1 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"denom_creation_fee\"", + (gogoproto.nullable) = false + ]; + + // DenomCreationGasConsume defines the gas cost for creating a new denom. + // This is intended as a spam deterrence mechanism. + // + // See: https://github.com/CosmWasm/token-factory/issues/11 + uint64 denom_creation_gas_consume = 2 [ + (gogoproto.moretags) = "yaml:\"denom_creation_gas_consume\"", + (gogoproto.nullable) = true + ]; + + // FeeCollectorAddress is the address where fees collected from denom creation + // are sent to + string fee_collector_address = 3; + repeated HookWhitelist whitelisted_hooks = 4; +} diff --git a/proto/osmosis/tokenfactory/v1beta1/genesis.proto b/proto/osmosis/tokenfactory/v1beta1/genesis.proto index a7d695544..11c97c5f3 100644 --- a/proto/osmosis/tokenfactory/v1beta1/genesis.proto +++ b/proto/osmosis/tokenfactory/v1beta1/genesis.proto @@ -2,8 +2,8 @@ syntax = "proto3"; package osmosis.tokenfactory.v1beta1; import "gogoproto/gogo.proto"; +import "osmosis/tokenfactory/params.proto"; import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto"; -import "osmosis/tokenfactory/v1beta1/params.proto"; option go_package = "github.com/neutron-org/neutron/v4/x/tokenfactory/types"; diff --git a/proto/osmosis/tokenfactory/v1beta1/params.proto b/proto/osmosis/tokenfactory/v1beta1/params.proto index 08d702017..e7e8b1b7a 100644 --- a/proto/osmosis/tokenfactory/v1beta1/params.proto +++ b/proto/osmosis/tokenfactory/v1beta1/params.proto @@ -5,7 +5,7 @@ import "cosmos/base/v1beta1/coin.proto"; import "cosmos_proto/cosmos.proto"; import "gogoproto/gogo.proto"; -option go_package = "github.com/neutron-org/neutron/v4/x/tokenfactory/types"; +option go_package = "github.com/neutron-org/neutron/v4/x/tokenfactory/types/v1beta1"; // Params defines the parameters for the tokenfactory module. message Params { diff --git a/proto/osmosis/tokenfactory/v1beta1/query.proto b/proto/osmosis/tokenfactory/v1beta1/query.proto index b01ab2344..d7b4d6f8d 100644 --- a/proto/osmosis/tokenfactory/v1beta1/query.proto +++ b/proto/osmosis/tokenfactory/v1beta1/query.proto @@ -3,8 +3,8 @@ package osmosis.tokenfactory.v1beta1; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; +import "osmosis/tokenfactory/params.proto"; import "osmosis/tokenfactory/v1beta1/authorityMetadata.proto"; -import "osmosis/tokenfactory/v1beta1/params.proto"; option go_package = "github.com/neutron-org/neutron/v4/x/tokenfactory/types"; diff --git a/proto/osmosis/tokenfactory/v1beta1/tx.proto b/proto/osmosis/tokenfactory/v1beta1/tx.proto index 2cf3f7fb7..e122fe71f 100644 --- a/proto/osmosis/tokenfactory/v1beta1/tx.proto +++ b/proto/osmosis/tokenfactory/v1beta1/tx.proto @@ -7,7 +7,7 @@ import "cosmos/base/v1beta1/coin.proto"; import "cosmos/msg/v1/msg.proto"; import "cosmos_proto/cosmos.proto"; import "gogoproto/gogo.proto"; -import "osmosis/tokenfactory/v1beta1/params.proto"; +import "osmosis/tokenfactory/params.proto"; option go_package = "github.com/neutron-org/neutron/v4/x/tokenfactory/types"; diff --git a/wasmbinding/test/custom_message_test.go b/wasmbinding/test/custom_message_test.go index 95c4519e1..760417c16 100644 --- a/wasmbinding/test/custom_message_test.go +++ b/wasmbinding/test/custom_message_test.go @@ -76,6 +76,7 @@ func (suite *CustomMessengerTestSuite) SetupTest() { sdk.NewCoins(sdk.NewInt64Coin(params.DefaultDenom, 10_000_000)), 0, FeeCollectorAddress, + tokenfactorytypes.DefaultWhitelistedHooks, )) suite.Require().NoError(err) diff --git a/wasmbinding/test/custom_query_test.go b/wasmbinding/test/custom_query_test.go index 8bef356d5..781151936 100644 --- a/wasmbinding/test/custom_query_test.go +++ b/wasmbinding/test/custom_query_test.go @@ -255,6 +255,7 @@ func (suite *CustomQuerierTestSuite) TestDenomAdmin() { sdk.NewCoins(sdk.NewInt64Coin(params.DefaultDenom, 10_000_000)), 0, FeeCollectorAddress, + tokenfactorytypes.DefaultWhitelistedHooks, )) suite.Require().NoError(err) diff --git a/x/tokenfactory/keeper/before_send.go b/x/tokenfactory/keeper/before_send.go index 69befbb7f..81e25796e 100644 --- a/x/tokenfactory/keeper/before_send.go +++ b/x/tokenfactory/keeper/before_send.go @@ -99,6 +99,11 @@ func (k Keeper) callBeforeSendListener(ctx context.Context, from, to sdk.AccAddr return err } + // Do not invoke hook if denom is not whitelisted and `from` is a module + if !k.isHookWhitelisted(c, coin.Denom, cwAddr) { + return nil + } + var msgBz []byte // get msgBz, either BlockBeforeSend or TrackBeforeSend diff --git a/x/tokenfactory/keeper/before_send_test.go b/x/tokenfactory/keeper/before_send_test.go index 540452d0e..0378ab92f 100644 --- a/x/tokenfactory/keeper/before_send_test.go +++ b/x/tokenfactory/keeper/before_send_test.go @@ -67,6 +67,24 @@ func (suite *KeeperTestSuite) TestTrackBeforeSendWasm() { queryResp, err := suite.GetNeutronZoneApp(suite.ChainA).WasmKeeper.QuerySmart(suite.ChainA.GetContext(), cosmwasmAddress, []byte(`{"total_supply_at":{}}`)) suite.Require().NoError(err) + + // Contract has not been called because it is not whitelisted + suite.Require().Equal("\"0\"", string(queryResp)) + + // Whitelist the hook + params := types.DefaultParams() + params.WhitelistedHooks = []*types.HookWhitelist{{DenomCreator: senderAddress.String(), CodeID: codeID}} + err = suite.GetNeutronZoneApp(suite.ChainA).TokenFactoryKeeper.SetParams(suite.ChainA.GetContext(), params) + suite.Require().NoError(err) + + // mint tokens again + _, err = suite.msgServer.Mint(suite.ChainA.GetContext(), types.NewMsgMint(suite.TestAccs[0].String(), tokenToSend)) + suite.Require().NoError(err) + + queryResp, err = suite.GetNeutronZoneApp(suite.ChainA).WasmKeeper.QuerySmart(suite.ChainA.GetContext(), cosmwasmAddress, []byte(`{"total_supply_at":{}}`)) + suite.Require().NoError(err) + + // Whitelisted contract has now been called suite.Require().Equal("\"100\"", string(queryResp)) }) } diff --git a/x/tokenfactory/keeper/keeper_test.go b/x/tokenfactory/keeper/keeper_test.go index 335ff509e..ac371decf 100644 --- a/x/tokenfactory/keeper/keeper_test.go +++ b/x/tokenfactory/keeper/keeper_test.go @@ -57,6 +57,7 @@ func (suite *KeeperTestSuite) Setup() { sdktypes.NewCoins(sdktypes.NewInt64Coin(params.DefaultDenom, TopUpCoinsAmount)), 0, FeeCollectorAddress, + types.DefaultWhitelistedHooks, )) suite.Require().NoError(err) diff --git a/x/tokenfactory/keeper/params.go b/x/tokenfactory/keeper/params.go index 4faa1764d..e9e124f7b 100644 --- a/x/tokenfactory/keeper/params.go +++ b/x/tokenfactory/keeper/params.go @@ -29,3 +29,24 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error { store.Set(types.ParamsKey, bz) return nil } + +func (k Keeper) isHookWhitelisted(ctx sdk.Context, denom string, contractAddress sdk.AccAddress) bool { + contractInfo := k.contractKeeper.GetContractInfo(ctx, contractAddress) + if contractInfo == nil { + return false + } + codeID := contractInfo.CodeID + whitelistedHooks := k.GetParams(ctx).WhitelistedHooks + denomCreator, _, err := types.DeconstructDenom(denom) + if err != nil { + return false + } + + for _, hook := range whitelistedHooks { + if hook.CodeID == codeID && hook.DenomCreator == denomCreator { + return true + } + } + + return false +} diff --git a/x/tokenfactory/types/expected_keepers.go b/x/tokenfactory/types/expected_keepers.go index 6c65d173b..45e7d8b0e 100644 --- a/x/tokenfactory/types/expected_keepers.go +++ b/x/tokenfactory/types/expected_keepers.go @@ -3,6 +3,7 @@ package types import ( "context" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) @@ -36,4 +37,5 @@ type BankHooks interface { type ContractKeeper interface { Sudo(ctx context.Context, contractAddress sdk.AccAddress, msg []byte) ([]byte, error) + GetContractInfo(ctx context.Context, contractAddress sdk.AccAddress) *wasmtypes.ContractInfo } diff --git a/x/tokenfactory/types/genesis.pb.go b/x/tokenfactory/types/genesis.pb.go index 29435e226..5f90a3d83 100644 --- a/x/tokenfactory/types/genesis.pb.go +++ b/x/tokenfactory/types/genesis.pb.go @@ -143,30 +143,31 @@ func init() { } var fileDescriptor_5749c3f71850298b = []byte{ - // 368 bytes of a gzipped FileDescriptorProto + // 370 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0xca, 0x2f, 0xce, 0xcd, 0x2f, 0xce, 0x2c, 0xd6, 0x2f, 0xc9, 0xcf, 0x4e, 0xcd, 0x4b, 0x4b, 0x4c, 0x2e, 0xc9, 0x2f, 0xaa, 0xd4, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x81, 0xaa, 0xd5, 0x43, 0x56, 0xab, 0x07, 0x55, - 0x2b, 0x25, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0x56, 0xa8, 0x0f, 0x62, 0x41, 0xf4, 0x48, 0x99, 0xe0, - 0x35, 0x3f, 0xb1, 0xb4, 0x24, 0x23, 0xbf, 0x28, 0xb3, 0xa4, 0xd2, 0x37, 0xb5, 0x24, 0x31, 0x25, - 0xb1, 0x24, 0x11, 0xaa, 0x4b, 0x13, 0xaf, 0xae, 0x82, 0xc4, 0xa2, 0xc4, 0x5c, 0xa8, 0xa3, 0x94, - 0x8e, 0x30, 0x72, 0xf1, 0xb8, 0x43, 0x9c, 0x19, 0x5c, 0x92, 0x58, 0x92, 0x2a, 0xe4, 0xc4, 0xc5, - 0x06, 0x51, 0x20, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0xa4, 0xa2, 0x87, 0xcf, 0xd9, 0x7a, 0x01, - 0x60, 0xb5, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x41, 0x75, 0x0a, 0x15, 0x70, 0xf1, 0x41, - 0xd5, 0xc5, 0xa7, 0xa4, 0xe6, 0xe5, 0xe7, 0x16, 0x4b, 0x30, 0x29, 0x30, 0x6b, 0x70, 0x1b, 0x69, - 0xe1, 0x37, 0x0b, 0xea, 0x0e, 0x17, 0x90, 0x16, 0x27, 0x59, 0x90, 0x89, 0x9f, 0xee, 0xc9, 0x8b, - 0x56, 0x26, 0xe6, 0xe6, 0x58, 0x29, 0xa1, 0x9a, 0xa7, 0x14, 0xc4, 0x0b, 0x15, 0x70, 0x81, 0xf0, - 0x8f, 0x22, 0xbc, 0x01, 0x16, 0x11, 0x52, 0xe3, 0x62, 0x05, 0x2b, 0x05, 0xfb, 0x82, 0xd3, 0x49, - 0xe0, 0xd3, 0x3d, 0x79, 0x1e, 0x88, 0x49, 0x60, 0x61, 0xa5, 0x20, 0x88, 0xb4, 0x50, 0x1b, 0x23, - 0x97, 0x10, 0x3c, 0x18, 0xe3, 0x73, 0xa1, 0xe1, 0x28, 0xc1, 0x04, 0xf6, 0xbb, 0x09, 0x7e, 0xf7, - 0x82, 0x6d, 0x72, 0x44, 0x8f, 0x03, 0x27, 0x45, 0xa8, 0xcb, 0x25, 0x21, 0xf6, 0x61, 0x9a, 0xae, - 0x14, 0x24, 0x88, 0x11, 0x73, 0x56, 0x2c, 0x2f, 0x16, 0xc8, 0x33, 0x3a, 0x05, 0x9c, 0x78, 0x24, - 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, - 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x59, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, - 0x72, 0x7e, 0xae, 0x7e, 0x5e, 0x6a, 0x69, 0x49, 0x51, 0x7e, 0x9e, 0x6e, 0x7e, 0x51, 0x3a, 0x8c, - 0xad, 0x5f, 0x66, 0xa2, 0x5f, 0x81, 0x1a, 0xdf, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0xe0, - 0x78, 0x36, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xd1, 0xcf, 0x93, 0x08, 0xaa, 0x02, 0x00, 0x00, + 0x2b, 0x25, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0x56, 0xa8, 0x0f, 0x62, 0x41, 0xf4, 0x48, 0x29, 0x62, + 0x35, 0xbf, 0x20, 0xb1, 0x28, 0x31, 0x17, 0x6a, 0xac, 0x94, 0x09, 0x5e, 0x27, 0x24, 0x96, 0x96, + 0x64, 0xe4, 0x17, 0x65, 0x96, 0x54, 0xfa, 0xa6, 0x96, 0x24, 0xa6, 0x24, 0x96, 0x24, 0x42, 0x74, + 0x29, 0xed, 0x61, 0xe4, 0xe2, 0x71, 0x87, 0x38, 0x2f, 0xb8, 0x24, 0xb1, 0x24, 0x55, 0xc8, 0x8a, + 0x8b, 0x0d, 0x62, 0xac, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb7, 0x91, 0x8c, 0x1e, 0x56, 0xe7, 0x06, + 0x80, 0xd5, 0x38, 0xb1, 0x9c, 0xb8, 0x27, 0xcf, 0x10, 0x04, 0xd5, 0x21, 0x54, 0xc0, 0xc5, 0x07, + 0x95, 0x8f, 0x4f, 0x49, 0xcd, 0xcb, 0xcf, 0x2d, 0x96, 0x60, 0x52, 0x60, 0xd6, 0xe0, 0x36, 0xd2, + 0xd2, 0xc3, 0xe7, 0x65, 0x3d, 0xa8, 0xfd, 0x2e, 0x20, 0x2d, 0x4e, 0xb2, 0x20, 0x13, 0x3f, 0xdd, + 0x93, 0x17, 0xad, 0x4c, 0xcc, 0xcd, 0xb1, 0x52, 0x42, 0x35, 0x4f, 0x29, 0x88, 0x17, 0x2a, 0xe0, + 0x02, 0xe1, 0x1f, 0x45, 0x38, 0x1f, 0x2c, 0x22, 0xa4, 0xc6, 0xc5, 0x0a, 0x56, 0x0a, 0x76, 0x3d, + 0xa7, 0x93, 0xc0, 0xa7, 0x7b, 0xf2, 0x3c, 0x10, 0x93, 0xc0, 0xc2, 0x4a, 0x41, 0x10, 0x69, 0xa1, + 0x36, 0x46, 0x2e, 0x21, 0x78, 0x98, 0xc4, 0xe7, 0x42, 0x03, 0x45, 0x82, 0x09, 0xec, 0x67, 0x13, + 0xfc, 0xee, 0x05, 0xdb, 0xe4, 0x88, 0x1e, 0xa0, 0x4e, 0x8a, 0x50, 0x97, 0x4b, 0x42, 0xec, 0xc3, + 0x34, 0x5d, 0x29, 0x48, 0x10, 0x23, 0x1a, 0xac, 0x58, 0x5e, 0x2c, 0x90, 0x67, 0x74, 0x0a, 0x38, + 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, + 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xb3, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, + 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0xfd, 0xbc, 0xd4, 0xd2, 0x92, 0xa2, 0xfc, 0x3c, 0xdd, 0xfc, 0xa2, + 0x74, 0x18, 0x5b, 0xbf, 0xcc, 0x44, 0xbf, 0x02, 0x35, 0xca, 0x4b, 0x2a, 0x0b, 0x52, 0x8b, 0x93, + 0xd8, 0xc0, 0xf1, 0x6b, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x27, 0x7d, 0x62, 0x1f, 0x9a, 0x02, + 0x00, 0x00, } func (this *GenesisDenom) Equal(that interface{}) bool { diff --git a/x/tokenfactory/types/params.go b/x/tokenfactory/types/params.go index 2e587c27a..06c1f76aa 100644 --- a/x/tokenfactory/types/params.go +++ b/x/tokenfactory/types/params.go @@ -12,10 +12,12 @@ var ( KeyDenomCreationFee = []byte("DenomCreationFee") KeyDenomCreationGasConsume = []byte("DenomCreationGasConsume") KeyFeeCollectorAddress = []byte("FeeCollectorAddress") + KeyWhitelistedHooks = []byte("WhitelistedHooks") // We don't want to charge users for denom creation DefaultDenomCreationFee sdk.Coins DefaultDenomCreationGasConsume uint64 DefaultFeeCollectorAddress = "" + DefaultWhitelistedHooks = []*HookWhitelist{} ) // ParamKeyTable the param key table for tokenfactory module. @@ -23,17 +25,18 @@ func ParamKeyTable() paramtypes.KeyTable { return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) } -func NewParams(denomCreationFee sdk.Coins, denomCreationGasConsume uint64, feeCollectorAddress string) Params { +func NewParams(denomCreationFee sdk.Coins, denomCreationGasConsume uint64, feeCollectorAddress string, whitelistedHooks []*HookWhitelist) Params { return Params{ DenomCreationFee: denomCreationFee, DenomCreationGasConsume: denomCreationGasConsume, FeeCollectorAddress: feeCollectorAddress, + WhitelistedHooks: whitelistedHooks, } } // DefaultParams returns a default set of parameters func DefaultParams() Params { - return NewParams(DefaultDenomCreationFee, DefaultDenomCreationGasConsume, DefaultFeeCollectorAddress) + return NewParams(DefaultDenomCreationFee, DefaultDenomCreationGasConsume, DefaultFeeCollectorAddress, DefaultWhitelistedHooks) } // Validate validates params @@ -54,6 +57,10 @@ func (p Params) Validate() error { return fmt.Errorf("failed to validate params: %w", err) } + if err := validateWhitelistedHooks(p.WhitelistedHooks); err != nil { + return fmt.Errorf("failed to validate params: %w", err) + } + return nil } @@ -63,6 +70,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeyDenomCreationFee, &p.DenomCreationFee, validateDenomCreationFee), paramtypes.NewParamSetPair(KeyDenomCreationGasConsume, &p.DenomCreationGasConsume, validateDenomCreationGasConsume), paramtypes.NewParamSetPair(KeyFeeCollectorAddress, &p.FeeCollectorAddress, validateFeeCollectorAddress), + paramtypes.NewParamSetPair(KeyWhitelistedHooks, &p.WhitelistedHooks, validateWhitelistedHooks), } } @@ -105,3 +113,24 @@ func validateFeeCollectorAddress(i interface{}) error { return nil } + +func validateWhitelistedHooks(i interface{}) error { + hooks, ok := i.([]*HookWhitelist) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + seenHooks := map[string]bool{} + for _, hook := range hooks { + hookStr := hook.String() + if seenHooks[hookStr] { + return fmt.Errorf("duplicate whitelisted hook: %#v", hook) + } + seenHooks[hookStr] = true + _, err := sdk.AccAddressFromBech32(hook.DenomCreator) + if err != nil { + return fmt.Errorf("invalid denom creator address: %w", err) + } + } + return nil +} diff --git a/x/tokenfactory/types/params.pb.go b/x/tokenfactory/types/params.pb.go index fabd4e60f..d05e3c72d 100644 --- a/x/tokenfactory/types/params.pb.go +++ b/x/tokenfactory/types/params.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: osmosis/tokenfactory/v1beta1/params.proto +// source: osmosis/tokenfactory/params.proto package types @@ -27,6 +27,58 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +type HookWhitelist struct { + CodeID uint64 `protobuf:"varint,1,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` + DenomCreator string `protobuf:"bytes,2,opt,name=denom_creator,json=denomCreator,proto3" json:"denom_creator,omitempty"` +} + +func (m *HookWhitelist) Reset() { *m = HookWhitelist{} } +func (m *HookWhitelist) String() string { return proto.CompactTextString(m) } +func (*HookWhitelist) ProtoMessage() {} +func (*HookWhitelist) Descriptor() ([]byte, []int) { + return fileDescriptor_09c297db7c49d1cf, []int{0} +} +func (m *HookWhitelist) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HookWhitelist) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HookWhitelist.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 *HookWhitelist) XXX_Merge(src proto.Message) { + xxx_messageInfo_HookWhitelist.Merge(m, src) +} +func (m *HookWhitelist) XXX_Size() int { + return m.Size() +} +func (m *HookWhitelist) XXX_DiscardUnknown() { + xxx_messageInfo_HookWhitelist.DiscardUnknown(m) +} + +var xxx_messageInfo_HookWhitelist proto.InternalMessageInfo + +func (m *HookWhitelist) GetCodeID() uint64 { + if m != nil { + return m.CodeID + } + return 0 +} + +func (m *HookWhitelist) GetDenomCreator() string { + if m != nil { + return m.DenomCreator + } + return "" +} + // Params defines the parameters for the tokenfactory module. type Params struct { // DenomCreationFee defines the fee to be charged on the creation of a new @@ -40,14 +92,15 @@ type Params struct { DenomCreationGasConsume uint64 `protobuf:"varint,2,opt,name=denom_creation_gas_consume,json=denomCreationGasConsume,proto3" json:"denom_creation_gas_consume,omitempty" yaml:"denom_creation_gas_consume"` // FeeCollectorAddress is the address where fees collected from denom creation // are sent to - FeeCollectorAddress string `protobuf:"bytes,3,opt,name=fee_collector_address,json=feeCollectorAddress,proto3" json:"fee_collector_address,omitempty"` + FeeCollectorAddress string `protobuf:"bytes,3,opt,name=fee_collector_address,json=feeCollectorAddress,proto3" json:"fee_collector_address,omitempty"` + WhitelistedHooks []*HookWhitelist `protobuf:"bytes,4,rep,name=whitelisted_hooks,json=whitelistedHooks,proto3" json:"whitelisted_hooks,omitempty"` } func (m *Params) Reset() { *m = Params{} } func (m *Params) String() string { return proto.CompactTextString(m) } func (*Params) ProtoMessage() {} func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_cc8299d306f3ff47, []int{0} + return fileDescriptor_09c297db7c49d1cf, []int{1} } func (m *Params) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -97,40 +150,86 @@ func (m *Params) GetFeeCollectorAddress() string { return "" } -func init() { - proto.RegisterType((*Params)(nil), "osmosis.tokenfactory.v1beta1.Params") +func (m *Params) GetWhitelistedHooks() []*HookWhitelist { + if m != nil { + return m.WhitelistedHooks + } + return nil } func init() { - proto.RegisterFile("osmosis/tokenfactory/v1beta1/params.proto", fileDescriptor_cc8299d306f3ff47) -} - -var fileDescriptor_cc8299d306f3ff47 = []byte{ - // 372 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0xb1, 0x6e, 0xe2, 0x40, - 0x10, 0xf5, 0xc2, 0x09, 0xe9, 0x7c, 0xcd, 0xc9, 0x77, 0x51, 0x00, 0x45, 0x36, 0x71, 0x65, 0x0a, - 0xbc, 0x82, 0x44, 0x29, 0xd2, 0x05, 0x4b, 0x49, 0x15, 0x09, 0x51, 0xa6, 0xb1, 0xd6, 0xf6, 0xd8, - 0xb1, 0xc0, 0x3b, 0xc8, 0xbb, 0xa0, 0xf0, 0x17, 0xa9, 0xf2, 0x11, 0xf9, 0x87, 0xf4, 0x94, 0x94, - 0xa9, 0x9c, 0x08, 0xfe, 0x80, 0x2f, 0x88, 0xb0, 0x4d, 0x04, 0x49, 0xaa, 0x9d, 0x99, 0xf7, 0xe6, - 0xcd, 0xdb, 0xd9, 0x55, 0xdb, 0x28, 0x12, 0x14, 0xb1, 0xa0, 0x12, 0x47, 0xc0, 0x43, 0xe6, 0x4b, - 0x4c, 0xe7, 0x74, 0xd6, 0xf5, 0x40, 0xb2, 0x2e, 0x9d, 0xb0, 0x94, 0x25, 0xc2, 0x9e, 0xa4, 0x28, - 0x51, 0x3b, 0x29, 0xa9, 0xf6, 0x3e, 0xd5, 0x2e, 0xa9, 0x4d, 0xdd, 0xcf, 0x61, 0xea, 0x31, 0x01, - 0x9f, 0xfd, 0x3e, 0xc6, 0xbc, 0xe8, 0x6e, 0x36, 0x0a, 0xdc, 0xcd, 0x33, 0x5a, 0x24, 0x25, 0xf4, - 0x3f, 0xc2, 0x08, 0x8b, 0xfa, 0x36, 0x2a, 0xaa, 0xe6, 0x4b, 0x45, 0xad, 0x0d, 0xf2, 0xf9, 0xda, - 0x13, 0x51, 0xb5, 0x00, 0x38, 0x26, 0xae, 0x9f, 0x02, 0x93, 0x31, 0x72, 0x37, 0x04, 0xa8, 0x93, - 0x56, 0xd5, 0xfa, 0xd3, 0x6b, 0xd8, 0xa5, 0xd8, 0x76, 0xf2, 0xce, 0x8e, 0xed, 0x60, 0xcc, 0xfb, - 0xb7, 0x8b, 0xcc, 0x50, 0x36, 0x99, 0xd1, 0x98, 0xb3, 0x64, 0x7c, 0x69, 0x7e, 0x97, 0x30, 0x9f, - 0xdf, 0x0c, 0x2b, 0x8a, 0xe5, 0xfd, 0xd4, 0xb3, 0x7d, 0x4c, 0x4a, 0x5b, 0xe5, 0xd1, 0x11, 0xc1, - 0x88, 0xca, 0xf9, 0x04, 0x44, 0xae, 0x26, 0x86, 0x7f, 0x73, 0x01, 0xa7, 0xec, 0xbf, 0x06, 0xd0, - 0x42, 0xb5, 0xf9, 0x45, 0x34, 0x62, 0xc2, 0xf5, 0x91, 0x8b, 0x69, 0x02, 0xf5, 0x4a, 0x8b, 0x58, - 0xbf, 0xfa, 0xed, 0x45, 0x66, 0x90, 0x4d, 0x66, 0x9c, 0xfe, 0x68, 0x62, 0x8f, 0x6f, 0x0e, 0x8f, - 0x0f, 0x06, 0xdc, 0x30, 0xe1, 0x14, 0x88, 0xd6, 0x53, 0x8f, 0x42, 0x00, 0xd7, 0xc7, 0xf1, 0x18, - 0xb6, 0x6b, 0x77, 0x59, 0x10, 0xa4, 0x20, 0x44, 0xbd, 0xda, 0x22, 0xd6, 0xef, 0xe1, 0xbf, 0x10, - 0xc0, 0xd9, 0x61, 0x57, 0x05, 0xd4, 0x1f, 0x2c, 0x56, 0x3a, 0x59, 0xae, 0x74, 0xf2, 0xbe, 0xd2, - 0xc9, 0xe3, 0x5a, 0x57, 0x96, 0x6b, 0x5d, 0x79, 0x5d, 0xeb, 0xca, 0xdd, 0xc5, 0xde, 0x8d, 0x39, - 0x4c, 0x65, 0x8a, 0xbc, 0x83, 0x69, 0xb4, 0x8b, 0xe9, 0xec, 0x9c, 0x3e, 0x1c, 0xfe, 0x87, 0x7c, - 0x0b, 0x5e, 0x2d, 0x7f, 0x98, 0xb3, 0x8f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb8, 0xfe, 0x4d, 0x2d, - 0x34, 0x02, 0x00, 0x00, + proto.RegisterType((*HookWhitelist)(nil), "osmosis.tokenfactory.HookWhitelist") + proto.RegisterType((*Params)(nil), "osmosis.tokenfactory.Params") +} + +func init() { proto.RegisterFile("osmosis/tokenfactory/params.proto", fileDescriptor_09c297db7c49d1cf) } + +var fileDescriptor_09c297db7c49d1cf = []byte{ + // 456 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0xb1, 0x8e, 0xd3, 0x40, + 0x10, 0x8d, 0x49, 0x14, 0xc4, 0xc2, 0x49, 0x87, 0x39, 0x84, 0x93, 0xc2, 0xce, 0x39, 0x4d, 0x28, + 0xce, 0xd6, 0x1d, 0x88, 0x82, 0x8e, 0x18, 0x01, 0x57, 0x20, 0x45, 0x6e, 0x10, 0x34, 0xd6, 0xc6, + 0x3b, 0x76, 0x56, 0x89, 0x77, 0x22, 0xef, 0xe6, 0x20, 0x5f, 0x01, 0x15, 0x1f, 0xc1, 0x97, 0xa4, + 0xbc, 0x92, 0xca, 0xa0, 0xe4, 0x0f, 0xee, 0x0b, 0x90, 0xd7, 0x8e, 0x70, 0xe0, 0x2a, 0xef, 0xbc, + 0x37, 0x33, 0x9e, 0xf7, 0x66, 0xc8, 0x29, 0xca, 0x0c, 0x25, 0x97, 0xbe, 0xc2, 0x39, 0x88, 0x84, + 0xc6, 0x0a, 0xf3, 0xb5, 0xbf, 0xa4, 0x39, 0xcd, 0xa4, 0xb7, 0xcc, 0x51, 0xa1, 0x79, 0x52, 0xa7, + 0x78, 0xcd, 0x94, 0xbe, 0x1d, 0x6b, 0xd8, 0x9f, 0x52, 0x09, 0xfe, 0xd5, 0xf9, 0x14, 0x14, 0x3d, + 0xf7, 0x63, 0xe4, 0xa2, 0xaa, 0xea, 0xf7, 0x2a, 0x3e, 0xd2, 0x91, 0x5f, 0x05, 0x35, 0x75, 0x92, + 0x62, 0x8a, 0x15, 0x5e, 0xbe, 0x2a, 0xd4, 0xfd, 0x48, 0x8e, 0xde, 0x21, 0xce, 0x3f, 0xcc, 0xb8, + 0x82, 0x05, 0x97, 0xca, 0x1c, 0x92, 0xbb, 0x31, 0x32, 0x88, 0x38, 0xb3, 0x8c, 0x81, 0x31, 0xea, + 0x8c, 0xc9, 0xb6, 0x70, 0xba, 0x01, 0x32, 0xb8, 0x7c, 0x1d, 0x76, 0x4b, 0xea, 0x92, 0x99, 0x43, + 0x72, 0xc4, 0x40, 0x60, 0x16, 0xc5, 0x39, 0x50, 0x85, 0xb9, 0x75, 0x67, 0x60, 0x8c, 0xee, 0x85, + 0x0f, 0x34, 0x18, 0x54, 0x98, 0xfb, 0xb5, 0x4d, 0xba, 0x13, 0x2d, 0xc9, 0xfc, 0x6e, 0x10, 0xb3, + 0x51, 0xc0, 0x51, 0x44, 0x09, 0x80, 0x65, 0x0c, 0xda, 0xa3, 0xfb, 0x17, 0x3d, 0xaf, 0x9e, 0xb3, + 0x14, 0xe5, 0xd5, 0xa2, 0xbc, 0x00, 0xb9, 0x18, 0xbf, 0xdf, 0x14, 0x4e, 0xeb, 0xa6, 0x70, 0x7a, + 0x6b, 0x9a, 0x2d, 0x5e, 0xba, 0xff, 0xb7, 0x70, 0x7f, 0xfc, 0x72, 0x46, 0x29, 0x57, 0xb3, 0xd5, + 0xd4, 0x8b, 0x31, 0xab, 0x15, 0xd7, 0x9f, 0x33, 0xc9, 0xe6, 0xbe, 0x5a, 0x2f, 0x41, 0xea, 0x6e, + 0x32, 0x3c, 0xfe, 0x3b, 0x1f, 0x47, 0xf1, 0x06, 0xc0, 0x4c, 0x48, 0xff, 0x9f, 0xa6, 0x29, 0x95, + 0x51, 0x8c, 0x42, 0xae, 0x32, 0xd0, 0xaa, 0x3a, 0xe3, 0xa7, 0x9b, 0xc2, 0x31, 0x6e, 0x0a, 0xe7, + 0xf4, 0xd6, 0x21, 0x1a, 0xf9, 0x6e, 0xf8, 0xe4, 0xe0, 0x07, 0x6f, 0xa9, 0x0c, 0x2a, 0xc6, 0xbc, + 0x20, 0x8f, 0x13, 0x80, 0x28, 0xc6, 0xc5, 0x02, 0xca, 0x4d, 0x46, 0x94, 0xb1, 0x1c, 0xa4, 0xb4, + 0xda, 0xda, 0xb8, 0x47, 0x09, 0x40, 0xb0, 0xe7, 0x5e, 0x55, 0x94, 0x39, 0x21, 0x0f, 0x3f, 0xef, + 0xd7, 0x02, 0x2c, 0x9a, 0x21, 0xce, 0xa5, 0xd5, 0xd1, 0x96, 0x0d, 0xbd, 0xdb, 0xae, 0xc3, 0x3b, + 0xd8, 0x64, 0x78, 0xdc, 0xa8, 0x2e, 0x19, 0x39, 0x9e, 0x6c, 0xb6, 0xb6, 0x71, 0xbd, 0xb5, 0x8d, + 0xdf, 0x5b, 0xdb, 0xf8, 0xb6, 0xb3, 0x5b, 0xd7, 0x3b, 0xbb, 0xf5, 0x73, 0x67, 0xb7, 0x3e, 0xbd, + 0x68, 0x78, 0x28, 0x60, 0xa5, 0x72, 0x14, 0x67, 0x98, 0xa7, 0xfb, 0xb7, 0x7f, 0xf5, 0xdc, 0xff, + 0x72, 0x78, 0xac, 0xda, 0xd7, 0x69, 0x57, 0x5f, 0xd1, 0xb3, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, + 0x1d, 0x23, 0x36, 0x33, 0xd1, 0x02, 0x00, 0x00, +} + +func (m *HookWhitelist) 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 *HookWhitelist) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HookWhitelist) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.DenomCreator) > 0 { + i -= len(m.DenomCreator) + copy(dAtA[i:], m.DenomCreator) + i = encodeVarintParams(dAtA, i, uint64(len(m.DenomCreator))) + i-- + dAtA[i] = 0x12 + } + if m.CodeID != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.CodeID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -153,6 +252,20 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.WhitelistedHooks) > 0 { + for iNdEx := len(m.WhitelistedHooks) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.WhitelistedHooks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } if len(m.FeeCollectorAddress) > 0 { i -= len(m.FeeCollectorAddress) copy(dAtA[i:], m.FeeCollectorAddress) @@ -193,6 +306,22 @@ func encodeVarintParams(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *HookWhitelist) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CodeID != 0 { + n += 1 + sovParams(uint64(m.CodeID)) + } + l = len(m.DenomCreator) + if l > 0 { + n += 1 + l + sovParams(uint64(l)) + } + return n +} + func (m *Params) Size() (n int) { if m == nil { return 0 @@ -212,6 +341,12 @@ func (m *Params) Size() (n int) { if l > 0 { n += 1 + l + sovParams(uint64(l)) } + if len(m.WhitelistedHooks) > 0 { + for _, e := range m.WhitelistedHooks { + l = e.Size() + n += 1 + l + sovParams(uint64(l)) + } + } return n } @@ -221,6 +356,107 @@ func sovParams(x uint64) (n int) { func sozParams(x uint64) (n int) { return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (m *HookWhitelist) 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 ErrIntOverflowParams + } + 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: HookWhitelist: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HookWhitelist: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeID", wireType) + } + m.CodeID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CodeID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DenomCreator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DenomCreator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Params) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -335,6 +571,40 @@ func (m *Params) Unmarshal(dAtA []byte) error { } m.FeeCollectorAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WhitelistedHooks", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.WhitelistedHooks = append(m.WhitelistedHooks, &HookWhitelist{}) + if err := m.WhitelistedHooks[len(m.WhitelistedHooks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/tokenfactory/types/query.pb.go b/x/tokenfactory/types/query.pb.go index 2e62dcd7f..3d6b122ff 100644 --- a/x/tokenfactory/types/query.pb.go +++ b/x/tokenfactory/types/query.pb.go @@ -419,50 +419,50 @@ func init() { } var fileDescriptor_6f22013ad0f72e3f = []byte{ - // 673 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x95, 0xcf, 0x4f, 0x13, 0x41, - 0x14, 0xc7, 0x3b, 0xa8, 0x55, 0x46, 0xd1, 0x30, 0xa0, 0xc1, 0x06, 0xb7, 0x32, 0x12, 0x03, 0x09, - 0x76, 0x04, 0x89, 0x07, 0x91, 0x08, 0x8b, 0x31, 0x26, 0x86, 0x04, 0x57, 0x62, 0x22, 0x31, 0x69, - 0xa6, 0xdd, 0xa1, 0x34, 0xb0, 0xfb, 0xca, 0xcc, 0x94, 0xd8, 0x10, 0x2e, 0x98, 0x78, 0x36, 0xf1, - 0xe8, 0xff, 0xe0, 0xdf, 0xc1, 0x91, 0x84, 0x8b, 0xa7, 0xc6, 0x80, 0x7f, 0x41, 0x0f, 0x5e, 0xbc, - 0x98, 0xce, 0xce, 0xf2, 0xc3, 0x96, 0x4d, 0x85, 0xc4, 0xdb, 0x76, 0xe6, 0xbd, 0xef, 0xfb, 0x7e, - 0xe6, 0xbd, 0x97, 0xe2, 0x11, 0x50, 0x01, 0xa8, 0xb2, 0x62, 0x1a, 0x56, 0x45, 0xb8, 0xcc, 0x8b, - 0x1a, 0x64, 0x8d, 0x6d, 0x8c, 0x17, 0x84, 0xe6, 0xe3, 0x6c, 0xbd, 0x2a, 0x64, 0x2d, 0x57, 0x91, - 0xa0, 0x81, 0x0c, 0xda, 0xc8, 0xdc, 0xf1, 0xc8, 0x9c, 0x8d, 0xcc, 0xf4, 0x97, 0xa0, 0x04, 0x26, - 0x90, 0x35, 0xbf, 0xa2, 0x9c, 0xcc, 0x60, 0x09, 0xa0, 0xb4, 0x26, 0x18, 0xaf, 0x94, 0x19, 0x0f, - 0x43, 0xd0, 0x5c, 0x97, 0x21, 0x54, 0xf6, 0x76, 0x32, 0xb1, 0x36, 0xaf, 0xea, 0x15, 0x90, 0x65, - 0x5d, 0x9b, 0x17, 0x9a, 0xfb, 0x5c, 0x73, 0x9b, 0x35, 0x9a, 0x98, 0x55, 0xe1, 0x92, 0x07, 0xb6, - 0x00, 0xed, 0xc7, 0xe4, 0x75, 0x93, 0x60, 0xc1, 0x1c, 0x7a, 0x62, 0xbd, 0x2a, 0x94, 0xa6, 0xef, - 0x70, 0xdf, 0x89, 0x53, 0x55, 0x81, 0x50, 0x09, 0xe2, 0xe2, 0x74, 0x94, 0x3c, 0x80, 0xee, 0xa2, - 0x91, 0xab, 0x13, 0xc3, 0xb9, 0x24, 0xe0, 0x5c, 0x94, 0xed, 0x5e, 0xdc, 0xa9, 0x67, 0x53, 0x9e, - 0xcd, 0xa4, 0x1f, 0x11, 0xa6, 0x46, 0xfb, 0xb9, 0x08, 0x21, 0x98, 0xfd, 0x9b, 0xc0, 0x3a, 0x20, - 0x63, 0xf8, 0x72, 0x51, 0x0a, 0xae, 0x41, 0x9a, 0x5a, 0xdd, 0x2e, 0x69, 0xd4, 0xb3, 0xd7, 0x6b, - 0x3c, 0x58, 0x7b, 0x42, 0xed, 0x05, 0xf5, 0xe2, 0x10, 0xc2, 0xf0, 0x15, 0x55, 0x2d, 0xf8, 0x4d, - 0xc5, 0x81, 0x2e, 0x13, 0xde, 0xd7, 0xa8, 0x67, 0x6f, 0x44, 0xe1, 0xf1, 0x0d, 0xf5, 0x0e, 0x83, - 0xe8, 0x37, 0x84, 0xef, 0x25, 0xba, 0xb0, 0xc4, 0x9f, 0x10, 0x26, 0x87, 0xaf, 0x9c, 0x0f, 0xec, - 0xb5, 0xc5, 0x9f, 0x4c, 0xc6, 0x6f, 0x2f, 0xed, 0x0e, 0x35, 0x9f, 0xa3, 0x51, 0xcf, 0xde, 0x8e, - 0xdc, 0xb5, 0xaa, 0x53, 0xaf, 0xb7, 0xa5, 0xb1, 0x74, 0x1e, 0xdf, 0x39, 0xf2, 0xab, 0x5e, 0x48, - 0x08, 0xe6, 0x22, 0xf6, 0x33, 0x3d, 0x18, 0x7d, 0x85, 0x9d, 0xd3, 0xe4, 0x2c, 0xf9, 0x28, 0x4e, - 0x9b, 0xa7, 0x6a, 0xf6, 0xfa, 0xc2, 0x48, 0xb7, 0xdb, 0xdb, 0xa8, 0x67, 0x7b, 0x22, 0xb9, 0xe8, - 0x9c, 0x7a, 0x36, 0x80, 0x6e, 0x23, 0x3c, 0x64, 0xd4, 0x5c, 0xb1, 0x0c, 0x52, 0xbc, 0x11, 0xa1, - 0xff, 0x12, 0x60, 0x75, 0xd6, 0xf7, 0xa5, 0x50, 0xea, 0x3f, 0x75, 0xb4, 0x68, 0xc7, 0xea, 0x14, - 0x0f, 0x96, 0x6a, 0x1a, 0xf7, 0x14, 0x21, 0xd4, 0x92, 0x17, 0x75, 0x9e, 0xfb, 0x7e, 0x6c, 0x65, - 0xa0, 0x51, 0xcf, 0xf6, 0x5b, 0x2b, 0xc7, 0xaf, 0xa9, 0x77, 0x2d, 0xfe, 0xdd, 0x54, 0x9a, 0x68, - 0xa4, 0xf1, 0x25, 0x53, 0x85, 0x7c, 0x45, 0x38, 0x1d, 0xcd, 0x37, 0x79, 0x98, 0x3c, 0x06, 0xad, - 0xeb, 0x95, 0x19, 0xff, 0x87, 0x8c, 0xc8, 0x38, 0x1d, 0xdb, 0xde, 0xfb, 0xf9, 0xa5, 0xeb, 0x3e, - 0x19, 0x66, 0x1d, 0xec, 0x36, 0xf9, 0x8d, 0xf0, 0xad, 0xf6, 0xe3, 0x47, 0x66, 0x3a, 0xa8, 0x9d, - 0xb8, 0x9a, 0x99, 0xd9, 0x73, 0x28, 0x58, 0x9a, 0xf7, 0x86, 0xe6, 0x2d, 0x59, 0x4c, 0xa6, 0x89, - 0xe6, 0x8b, 0xc5, 0xc7, 0x9b, 0x76, 0x38, 0xb6, 0xd8, 0x66, 0xdc, 0xf6, 0x2d, 0xd6, 0xba, 0x3f, - 0x64, 0x0f, 0xe1, 0xde, 0x96, 0xc1, 0x26, 0x53, 0x9d, 0xda, 0x6e, 0xb3, 0x5d, 0x99, 0xa7, 0x67, - 0x4b, 0xb6, 0xb8, 0x73, 0x06, 0x77, 0x9a, 0x4c, 0x75, 0x82, 0x9b, 0x5f, 0x96, 0x10, 0xe4, 0x2d, - 0xea, 0x11, 0x33, 0xf9, 0x85, 0xf0, 0xcd, 0xb6, 0xc3, 0x4d, 0x9e, 0x75, 0x60, 0x2e, 0x69, 0x35, - 0x33, 0x33, 0x67, 0x17, 0xb0, 0x84, 0x4b, 0x86, 0x70, 0x91, 0x78, 0xe7, 0x6f, 0x68, 0xc1, 0x14, - 0xca, 0x2b, 0x11, 0xfa, 0xf9, 0x15, 0x80, 0x55, 0x77, 0x61, 0x67, 0xdf, 0x41, 0xbb, 0xfb, 0x0e, - 0xfa, 0xb1, 0xef, 0xa0, 0xcf, 0x07, 0x4e, 0x6a, 0xf7, 0xc0, 0x49, 0x7d, 0x3f, 0x70, 0x52, 0x4b, - 0x8f, 0x4b, 0x65, 0xbd, 0x52, 0x2d, 0xe4, 0x8a, 0x10, 0xb0, 0x50, 0x54, 0xb5, 0x84, 0xf0, 0x01, - 0xc8, 0x52, 0xfc, 0xcd, 0x36, 0x26, 0xd9, 0x87, 0x93, 0x46, 0x74, 0xad, 0x22, 0x54, 0x21, 0x6d, - 0xfe, 0xfb, 0x1e, 0xfd, 0x09, 0x00, 0x00, 0xff, 0xff, 0xca, 0x76, 0xec, 0xdc, 0xda, 0x07, 0x00, - 0x00, + // 677 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x4f, 0x4f, 0x13, 0x4f, + 0x18, 0xee, 0xf2, 0xfb, 0x59, 0x65, 0x14, 0x0d, 0x03, 0x1a, 0x6c, 0x70, 0x2b, 0xa3, 0x31, 0x98, + 0xe0, 0x8e, 0x20, 0xf1, 0x00, 0x12, 0xa1, 0x18, 0x63, 0x62, 0x48, 0x60, 0x25, 0x1e, 0x88, 0x49, + 0x33, 0xed, 0x0e, 0xa5, 0x81, 0xdd, 0xb7, 0xcc, 0x4c, 0x89, 0x0d, 0xe1, 0x82, 0x89, 0x67, 0x13, + 0x8f, 0x7e, 0x07, 0x3f, 0x07, 0x47, 0x12, 0x2e, 0x9e, 0x1a, 0x03, 0x7e, 0x82, 0x1e, 0xbc, 0x78, + 0x31, 0x9d, 0x99, 0xe5, 0x8f, 0x2d, 0x9b, 0x5a, 0x12, 0x6f, 0xdb, 0x79, 0x9f, 0xf7, 0x79, 0x9f, + 0xe7, 0xfd, 0x93, 0xa2, 0x51, 0x90, 0x21, 0xc8, 0xb2, 0xa4, 0x0a, 0xd6, 0x79, 0xb4, 0xca, 0x8a, + 0x0a, 0x44, 0x8d, 0x6e, 0x8d, 0x17, 0xb8, 0x62, 0xe3, 0x74, 0xb3, 0xca, 0x45, 0xcd, 0xab, 0x08, + 0x50, 0x80, 0x87, 0x2d, 0xd2, 0x3b, 0x8d, 0xf4, 0x2c, 0x32, 0x33, 0x58, 0x82, 0x12, 0x68, 0x20, + 0x6d, 0x7e, 0x99, 0x9c, 0xcc, 0x70, 0x09, 0xa0, 0xb4, 0xc1, 0x29, 0xab, 0x94, 0x29, 0x8b, 0x22, + 0x50, 0x4c, 0x95, 0x21, 0x92, 0x36, 0x3a, 0xd2, 0xb6, 0x76, 0x85, 0x09, 0x16, 0xc6, 0x90, 0xc9, + 0x44, 0x79, 0xac, 0xaa, 0xd6, 0x40, 0x94, 0x55, 0x6d, 0x81, 0x2b, 0x16, 0x30, 0xc5, 0x4c, 0x16, + 0x19, 0x44, 0x78, 0xa9, 0xa9, 0x7c, 0x51, 0x53, 0xf9, 0x7c, 0xb3, 0xca, 0xa5, 0x22, 0x4b, 0x68, + 0xe0, 0xcc, 0xab, 0xac, 0x40, 0x24, 0x39, 0x9e, 0x42, 0x69, 0x53, 0x72, 0xc8, 0xb9, 0xeb, 0x8c, + 0x5e, 0x9d, 0x18, 0xf6, 0xda, 0x1a, 0x35, 0x59, 0xb9, 0xff, 0xf7, 0xea, 0xd9, 0x94, 0x6f, 0x33, + 0xc8, 0x07, 0x07, 0x11, 0xcd, 0xf9, 0x82, 0x47, 0x10, 0xce, 0xfd, 0x29, 0xc7, 0x56, 0xc6, 0x63, + 0xe8, 0x72, 0x51, 0x70, 0xa6, 0x40, 0xe8, 0x1a, 0xbd, 0x39, 0xdc, 0xa8, 0x67, 0xaf, 0xd7, 0x58, + 0xb8, 0x31, 0x45, 0x6c, 0x80, 0xf8, 0x31, 0x04, 0x53, 0x74, 0x45, 0x56, 0x0b, 0x41, 0x93, 0x71, + 0xa8, 0x47, 0xc3, 0x07, 0x1a, 0xf5, 0xec, 0x0d, 0x03, 0x8f, 0x23, 0xc4, 0x3f, 0x06, 0x91, 0xaf, + 0x0e, 0xba, 0x97, 0xa8, 0xc2, 0x3a, 0xfd, 0xe8, 0x20, 0x7c, 0xdc, 0xb2, 0x7c, 0x68, 0xc3, 0xd6, + 0xf6, 0xa4, 0x97, 0x34, 0x5f, 0xaf, 0x3d, 0x75, 0x6e, 0xa4, 0xd9, 0x8e, 0x46, 0x3d, 0x7b, 0xdb, + 0xa8, 0x6b, 0x65, 0x27, 0x7e, 0x7f, 0xcb, 0x94, 0xc8, 0x02, 0xba, 0x73, 0xa2, 0x57, 0xbe, 0x14, + 0x10, 0xce, 0x1b, 0xef, 0x5d, 0x35, 0x8c, 0xbc, 0x46, 0xee, 0x79, 0x74, 0xd6, 0xf9, 0x43, 0x94, + 0xd6, 0xad, 0x6a, 0xce, 0xf8, 0xbf, 0xd1, 0xde, 0x5c, 0x7f, 0xa3, 0x9e, 0xed, 0x33, 0x74, 0xe6, + 0x9d, 0xf8, 0x16, 0x40, 0x76, 0x1d, 0x34, 0xa2, 0xd9, 0x72, 0x7c, 0x15, 0x04, 0x7f, 0xc3, 0xa3, + 0xe0, 0x15, 0xc0, 0xfa, 0x5c, 0x10, 0x08, 0x2e, 0xe5, 0x3f, 0x9a, 0x68, 0xd1, 0xae, 0xd5, 0x39, + 0x1a, 0xac, 0xab, 0x19, 0xd4, 0x57, 0x84, 0x48, 0x09, 0x56, 0x54, 0x79, 0x16, 0x04, 0xb1, 0x94, + 0xa1, 0x46, 0x3d, 0x3b, 0x68, 0xa5, 0x9c, 0x0e, 0x13, 0xff, 0x5a, 0xfc, 0xbb, 0xc9, 0x34, 0xd1, + 0x48, 0xa3, 0x4b, 0xba, 0x0a, 0xfe, 0xe2, 0xa0, 0xb4, 0xd9, 0x6f, 0xfc, 0x38, 0x79, 0x0d, 0x5a, + 0xcf, 0x2a, 0x33, 0xfe, 0x17, 0x19, 0x46, 0x38, 0x19, 0xdb, 0x3d, 0xf8, 0xf1, 0xb9, 0xe7, 0x01, + 0xbe, 0x4f, 0x13, 0xcf, 0xdb, 0x1c, 0x19, 0xfe, 0xe5, 0xa0, 0x5b, 0xed, 0xd7, 0x0f, 0xcf, 0x76, + 0x50, 0x3b, 0xf1, 0x34, 0x33, 0x73, 0x17, 0x60, 0xb0, 0x6e, 0xde, 0x69, 0x37, 0x6f, 0xf1, 0x72, + 0xb2, 0x1b, 0xb3, 0x5f, 0x34, 0x7e, 0xde, 0xb6, 0xcb, 0xb1, 0x43, 0xb7, 0xe3, 0xb1, 0xef, 0xd0, + 0xd6, 0xfb, 0xc1, 0x07, 0x0e, 0xea, 0x6f, 0x59, 0x6c, 0x3c, 0xdd, 0xa9, 0xec, 0x36, 0xd7, 0x95, + 0x79, 0xd6, 0x5d, 0xb2, 0xb5, 0x3b, 0xaf, 0xed, 0xce, 0xe0, 0xe9, 0x4e, 0xec, 0xe6, 0x57, 0x05, + 0x84, 0x79, 0x6b, 0xf5, 0xc4, 0x33, 0xfe, 0xe9, 0xa0, 0x9b, 0x6d, 0x97, 0x1b, 0x3f, 0xef, 0x40, + 0x5c, 0xd2, 0x69, 0x66, 0x66, 0xbb, 0x27, 0xb0, 0x0e, 0x57, 0xb4, 0xc3, 0x65, 0xec, 0x5f, 0x7c, + 0xa0, 0x05, 0x5d, 0x28, 0x2f, 0x79, 0x14, 0xe4, 0xd7, 0x00, 0xd6, 0x73, 0x8b, 0x7b, 0x87, 0xae, + 0xb3, 0x7f, 0xe8, 0x3a, 0xdf, 0x0f, 0x5d, 0xe7, 0xd3, 0x91, 0x9b, 0xda, 0x3f, 0x72, 0x53, 0xdf, + 0x8e, 0xdc, 0xd4, 0xca, 0xd3, 0x52, 0x59, 0xad, 0x55, 0x0b, 0x5e, 0x11, 0x42, 0x1a, 0xf1, 0xaa, + 0x12, 0x10, 0x3d, 0x02, 0x51, 0x8a, 0xbf, 0xe9, 0xd6, 0x24, 0x7d, 0x7f, 0x56, 0x88, 0xaa, 0x55, + 0xb8, 0x2c, 0xa4, 0xf5, 0x7f, 0xde, 0x93, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x7f, 0xf0, 0xc4, + 0xcf, 0xca, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/tokenfactory/types/tx.go b/x/tokenfactory/types/tx.go index b453ddb2f..3925b0b5a 100644 --- a/x/tokenfactory/types/tx.go +++ b/x/tokenfactory/types/tx.go @@ -32,9 +32,5 @@ func (msg *MsgUpdateParams) Validate() error { return errorsmod.Wrap(err, "authority is invalid") } - if _, err := sdk.AccAddressFromBech32(msg.Params.FeeCollectorAddress); err != nil { - return errorsmod.Wrap(err, "fee_collector_address is invalid") - } - - return nil + return msg.Params.Validate() } diff --git a/x/tokenfactory/types/tx.pb.go b/x/tokenfactory/types/tx.pb.go index 9e48c15bd..236c58ed4 100644 --- a/x/tokenfactory/types/tx.pb.go +++ b/x/tokenfactory/types/tx.pb.go @@ -857,74 +857,74 @@ func init() { } var fileDescriptor_283b6c9a90a846b4 = []byte{ - // 1062 bytes of a gzipped FileDescriptorProto + // 1064 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xce, 0xf6, 0x47, 0xda, 0x4c, 0x12, 0x92, 0x6c, 0x42, 0xe3, 0x2c, 0xa9, 0xb7, 0x2c, 0x14, - 0x35, 0x11, 0xf6, 0xca, 0x69, 0x88, 0xc0, 0x12, 0x12, 0x75, 0x51, 0xe8, 0x01, 0x4b, 0xd5, 0x26, - 0x5c, 0x50, 0x25, 0x6b, 0x6c, 0x4f, 0xd6, 0x2b, 0xb3, 0x33, 0xee, 0xcc, 0x38, 0x69, 0x6e, 0x15, - 0xdc, 0x38, 0xf1, 0x1f, 0x20, 0x2e, 0x88, 0x63, 0x0e, 0xfc, 0x11, 0xe1, 0x56, 0x71, 0xe2, 0xb4, - 0x42, 0xc9, 0x21, 0x07, 0x4e, 0xf8, 0x2f, 0x40, 0xf3, 0x63, 0xd7, 0xde, 0xb5, 0x15, 0xdb, 0x07, - 0xd4, 0x4b, 0xe2, 0x9d, 0xf7, 0x7d, 0x6f, 0xdf, 0xf7, 0xcd, 0x9b, 0x37, 0x36, 0x78, 0x48, 0x58, - 0x48, 0x58, 0xc0, 0x5c, 0x4e, 0xda, 0x08, 0x1f, 0xc1, 0x06, 0x27, 0xf4, 0xd4, 0x3d, 0x2e, 0xd5, - 0x11, 0x87, 0x25, 0x97, 0xbf, 0x2a, 0x76, 0x28, 0xe1, 0xc4, 0xdc, 0xd4, 0xb0, 0xe2, 0x20, 0xac, - 0xa8, 0x61, 0xd6, 0x0a, 0x0c, 0x03, 0x4c, 0x5c, 0xf9, 0x57, 0x11, 0xac, 0x7c, 0x43, 0x32, 0xdc, - 0x3a, 0xc4, 0xed, 0x24, 0x9d, 0x78, 0x18, 0x8a, 0x33, 0x94, 0xc4, 0x1b, 0x24, 0xc0, 0x3a, 0xbe, - 0xae, 0xe3, 0x21, 0xf3, 0xdd, 0xe3, 0x92, 0xf8, 0xa7, 0x03, 0x1b, 0x2a, 0x50, 0x93, 0x4f, 0xae, - 0x7a, 0xd0, 0xa1, 0x35, 0x9f, 0xf8, 0x44, 0xad, 0x8b, 0x4f, 0x7a, 0x75, 0xeb, 0x5a, 0x85, 0x1d, - 0x48, 0x61, 0xa8, 0x13, 0x38, 0x3f, 0x1b, 0xe0, 0x9d, 0x2a, 0xf3, 0x9f, 0x52, 0x04, 0x39, 0xfa, - 0x12, 0x61, 0x12, 0x9a, 0x5b, 0x60, 0x96, 0x21, 0xdc, 0x44, 0x34, 0x67, 0x3c, 0x30, 0x1e, 0xcd, - 0x55, 0x56, 0x7a, 0x91, 0xbd, 0x78, 0x0a, 0xc3, 0xef, 0xca, 0x8e, 0x5a, 0x77, 0x3c, 0x0d, 0x30, - 0x5d, 0x70, 0x97, 0x75, 0xeb, 0x4d, 0x41, 0xcb, 0xdd, 0x90, 0xe0, 0xd5, 0x5e, 0x64, 0x2f, 0x69, - 0xb0, 0x8e, 0x38, 0x5e, 0x02, 0x2a, 0x97, 0xbe, 0xbf, 0x3a, 0xdb, 0xd6, 0xec, 0x1f, 0xaf, 0xce, - 0xb6, 0xdf, 0x1f, 0x59, 0x69, 0x43, 0x56, 0x53, 0x50, 0xec, 0x17, 0xe0, 0x5e, 0xba, 0x40, 0x0f, - 0xb1, 0x0e, 0xc1, 0x0c, 0x99, 0x15, 0xb0, 0x84, 0xd1, 0x49, 0x4d, 0x52, 0x6b, 0xaa, 0x08, 0x55, - 0xb1, 0xd5, 0x8b, 0xec, 0x7b, 0xaa, 0x88, 0x0c, 0xc0, 0xf1, 0x16, 0x31, 0x3a, 0x39, 0x14, 0x0b, - 0x32, 0x97, 0xf3, 0x8f, 0x01, 0xee, 0x54, 0x99, 0x5f, 0x0d, 0x30, 0x9f, 0x46, 0xf8, 0x33, 0x30, - 0x0b, 0x43, 0xd2, 0xc5, 0x5c, 0xca, 0x9e, 0xdf, 0xd9, 0x28, 0xea, 0x6d, 0x11, 0x9b, 0x1b, 0x37, - 0x49, 0xf1, 0x29, 0x09, 0x70, 0xe5, 0xdd, 0xf3, 0xc8, 0x9e, 0xe9, 0x67, 0x52, 0x34, 0xc7, 0xd3, - 0x7c, 0xf3, 0x0b, 0xb0, 0x18, 0x06, 0x98, 0x1f, 0x92, 0x27, 0xcd, 0x26, 0x45, 0x8c, 0xe5, 0x6e, - 0x66, 0x25, 0x88, 0x70, 0x8d, 0x93, 0x1a, 0x54, 0x00, 0xc7, 0x4b, 0x13, 0xca, 0x5b, 0x19, 0x4f, - 0x37, 0x46, 0x7a, 0x2a, 0x38, 0xce, 0x0a, 0x58, 0xd2, 0x62, 0x63, 0x13, 0x9d, 0x7f, 0x95, 0x01, - 0x95, 0x2e, 0xc5, 0x6f, 0xc7, 0x80, 0x7d, 0xb0, 0x54, 0xef, 0x52, 0xbc, 0x4f, 0x49, 0x98, 0xb6, - 0x60, 0xb3, 0x17, 0xd9, 0x39, 0xc5, 0x11, 0x80, 0xda, 0x11, 0x25, 0x61, 0xdf, 0x84, 0x2c, 0x69, - 0x42, 0x1b, 0x04, 0x4b, 0xdb, 0x20, 0x24, 0x27, 0x36, 0xfc, 0xa1, 0xcf, 0x41, 0x0b, 0x62, 0x1f, - 0x3d, 0x69, 0x86, 0xc1, 0x54, 0x6e, 0x7c, 0x04, 0x6e, 0x0f, 0x1e, 0x82, 0xe5, 0x5e, 0x64, 0x2f, - 0x28, 0xa4, 0xee, 0x3a, 0x15, 0x36, 0x4b, 0x60, 0x4e, 0x34, 0x24, 0x14, 0xf9, 0xb5, 0xca, 0xb5, - 0x5e, 0x64, 0x2f, 0xf7, 0x7b, 0x55, 0x86, 0x1c, 0xef, 0x2e, 0x46, 0x27, 0xb2, 0x8a, 0x49, 0x4f, - 0x8c, 0xac, 0xbb, 0xa0, 0xd8, 0x39, 0x75, 0x62, 0xfa, 0x52, 0x12, 0x95, 0x17, 0x06, 0x58, 0xab, - 0x32, 0xff, 0x00, 0xf1, 0x0a, 0x3a, 0x22, 0x14, 0x1d, 0x20, 0xdc, 0x7c, 0x46, 0x48, 0xfb, 0xff, - 0xd0, 0xfa, 0x39, 0x58, 0x6c, 0x10, 0xcc, 0x29, 0x6c, 0x70, 0xb9, 0x6b, 0x5a, 0x6f, 0xae, 0x17, - 0xd9, 0x6b, 0x0a, 0x9f, 0x0a, 0x3b, 0xde, 0x42, 0xfc, 0x2c, 0x76, 0xb4, 0xfc, 0x69, 0x46, 0xf7, - 0xa3, 0x91, 0xba, 0x19, 0xe2, 0x85, 0xba, 0x94, 0x22, 0x90, 0x85, 0x16, 0x21, 0x6d, 0x27, 0x0f, - 0x36, 0x47, 0x69, 0x4c, 0x4c, 0xf8, 0xc5, 0x00, 0xab, 0x0a, 0x20, 0x47, 0x40, 0x15, 0x71, 0xd8, - 0x84, 0x1c, 0x4e, 0xe3, 0x81, 0x07, 0xee, 0x86, 0x9a, 0xa6, 0xfb, 0xff, 0x7e, 0xbf, 0xff, 0x71, - 0x3b, 0xe9, 0xff, 0x38, 0x77, 0x65, 0x5d, 0x9f, 0x01, 0x3d, 0x1a, 0x63, 0xb2, 0xe3, 0x25, 0x79, - 0xca, 0xf3, 0x03, 0x82, 0x9d, 0xfb, 0xe0, 0xbd, 0x11, 0x25, 0x26, 0x12, 0xa2, 0x1b, 0x60, 0xb9, - 0xca, 0xfc, 0x7d, 0x42, 0x1b, 0xe8, 0x90, 0x42, 0xcc, 0x8e, 0x10, 0x7d, 0x3b, 0xa7, 0xd7, 0x03, - 0xab, 0x5c, 0x17, 0x30, 0x7c, 0x82, 0x1f, 0xf4, 0x22, 0x7b, 0x53, 0xf1, 0x62, 0x50, 0xe6, 0x14, - 0x8f, 0x22, 0x9b, 0x5f, 0x83, 0x95, 0x78, 0xb9, 0x3f, 0x16, 0x6f, 0xc9, 0x8c, 0xf9, 0x5e, 0x64, - 0x5b, 0x99, 0x8c, 0x83, 0xa3, 0x71, 0x98, 0x58, 0x7e, 0x9c, 0x69, 0xa4, 0x0f, 0x46, 0x36, 0xd2, - 0x91, 0xb0, 0xb2, 0x10, 0xb3, 0x1d, 0x0b, 0xe4, 0xb2, 0xfe, 0x26, 0xe6, 0x9f, 0x1b, 0x72, 0x7c, - 0x7c, 0xd3, 0x69, 0x42, 0x8e, 0x9e, 0xcb, 0xcb, 0xd4, 0xdc, 0x03, 0x73, 0xb0, 0xcb, 0x5b, 0x84, - 0x06, 0xfc, 0x54, 0xdb, 0x9f, 0xfb, 0xf3, 0xf7, 0xc2, 0x9a, 0xb6, 0x55, 0xd7, 0x72, 0xc0, 0x69, - 0x80, 0x7d, 0xaf, 0x0f, 0x35, 0xbf, 0x02, 0xb3, 0xea, 0x3a, 0xd6, 0x1b, 0xf1, 0x61, 0xf1, 0xba, - 0x6f, 0x1d, 0x45, 0xf5, 0xb6, 0xca, 0x9c, 0xd8, 0x93, 0xdf, 0xae, 0xce, 0xb6, 0x0d, 0x4f, 0xd3, - 0xcb, 0xbb, 0x42, 0x65, 0x3f, 0xb1, 0x9c, 0x14, 0x01, 0xe6, 0x88, 0x36, 0x5a, 0x30, 0xc0, 0x2f, - 0xbb, 0x88, 0x06, 0x88, 0xb9, 0x99, 0xb2, 0x9d, 0x0d, 0xb0, 0x9e, 0x59, 0x8a, 0x55, 0xee, 0xfc, - 0x7a, 0x07, 0xdc, 0xac, 0x32, 0xdf, 0x7c, 0x09, 0xe6, 0x07, 0xbf, 0x1c, 0x7c, 0x7c, 0x7d, 0x81, - 0xe9, 0x9b, 0xda, 0xda, 0x9d, 0x06, 0x9d, 0xdc, 0xeb, 0x2f, 0xc0, 0x2d, 0x79, 0x1f, 0x3f, 0x1c, - 0xcb, 0x16, 0x30, 0xab, 0x30, 0x11, 0x6c, 0x30, 0xbb, 0xbc, 0xec, 0xc6, 0x67, 0x17, 0xb0, 0x09, - 0xb2, 0x0f, 0xde, 0x23, 0xd2, 0xae, 0x81, 0x3b, 0x64, 0x02, 0xbb, 0xfa, 0xe8, 0x49, 0xec, 0x1a, - 0x1e, 0xea, 0xe6, 0x6b, 0x03, 0x2c, 0x0f, 0x0d, 0xb3, 0xd2, 0xd8, 0x54, 0x59, 0x8a, 0xf5, 0xd9, - 0xd4, 0x94, 0xa4, 0x84, 0x1f, 0x0c, 0xb0, 0x32, 0x7c, 0xa9, 0xec, 0x4c, 0x92, 0x30, 0xcd, 0xb1, - 0xca, 0xd3, 0x73, 0x92, 0x2a, 0x4e, 0xc0, 0x62, 0x7a, 0x22, 0x16, 0xc7, 0x26, 0x4b, 0xe1, 0xad, - 0xbd, 0xe9, 0xf0, 0xc9, 0x8b, 0x39, 0x58, 0x48, 0x4d, 0x83, 0xf1, 0x3d, 0x33, 0x08, 0xb7, 0x3e, - 0x99, 0x0a, 0x1e, 0xbf, 0xd5, 0xba, 0xfd, 0x5a, 0x4c, 0x80, 0xca, 0xf3, 0xf3, 0x8b, 0xbc, 0xf1, - 0xe6, 0x22, 0x6f, 0xfc, 0x7d, 0x91, 0x37, 0x7e, 0xba, 0xcc, 0xcf, 0xbc, 0xb9, 0xcc, 0xcf, 0xfc, - 0x75, 0x99, 0x9f, 0xf9, 0x76, 0xcf, 0x0f, 0x78, 0xab, 0x5b, 0x2f, 0x36, 0x48, 0xe8, 0x62, 0xd4, - 0xe5, 0x94, 0xe0, 0x02, 0xa1, 0x7e, 0xfc, 0xd9, 0x3d, 0xde, 0x75, 0x5f, 0xa5, 0xa7, 0x20, 0x3f, - 0xed, 0x20, 0x56, 0x9f, 0x95, 0x3f, 0x0d, 0x1e, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x09, 0x23, - 0x7c, 0x64, 0x29, 0x0d, 0x00, 0x00, + 0x14, 0xce, 0xf6, 0x47, 0x9a, 0x4c, 0x12, 0x92, 0x6c, 0x42, 0xe3, 0x2c, 0xa9, 0xb7, 0x2c, 0x2a, + 0x6a, 0x23, 0xbc, 0x2b, 0xa7, 0x21, 0x02, 0x4b, 0x08, 0xea, 0xa2, 0xa8, 0x07, 0x2c, 0x55, 0x9b, + 0x70, 0x41, 0x95, 0xac, 0xb1, 0x3d, 0xd9, 0xac, 0xcc, 0xce, 0xb8, 0x33, 0xe3, 0xa4, 0xb9, 0x55, + 0x70, 0xe3, 0xc4, 0x7f, 0x80, 0xb8, 0x20, 0x8e, 0x39, 0xf0, 0x07, 0x70, 0x2c, 0xb7, 0x8a, 0x13, + 0xa7, 0x15, 0x4a, 0x0e, 0x39, 0x70, 0xc2, 0x7f, 0x01, 0x9a, 0x1f, 0xbb, 0xf6, 0xae, 0x2d, 0x6c, + 0x1f, 0xaa, 0x5e, 0x5a, 0xef, 0xbc, 0xef, 0x7b, 0xfb, 0xbe, 0x6f, 0xde, 0xbc, 0xd9, 0x80, 0x7b, + 0x84, 0x45, 0x84, 0x85, 0xcc, 0xe3, 0xa4, 0x8d, 0xf0, 0x11, 0x6c, 0x72, 0x42, 0xcf, 0xbc, 0x93, + 0x72, 0x03, 0x71, 0x58, 0xf6, 0xf8, 0x0b, 0xb7, 0x43, 0x09, 0x27, 0xe6, 0x96, 0x86, 0xb9, 0x83, + 0x30, 0x57, 0xc3, 0xac, 0x55, 0x18, 0x85, 0x98, 0x78, 0xf2, 0x5f, 0x45, 0xb0, 0x8a, 0x4d, 0xc9, + 0xf0, 0x1a, 0x10, 0xb7, 0xd3, 0x74, 0xe2, 0x61, 0x28, 0xce, 0x50, 0x1a, 0x6f, 0x92, 0x10, 0xeb, + 0xf8, 0x86, 0x8e, 0x47, 0x2c, 0xf0, 0x4e, 0xca, 0xe2, 0x3f, 0x1d, 0xd8, 0x54, 0x81, 0xba, 0x7c, + 0xf2, 0xd4, 0x83, 0x0e, 0xad, 0x07, 0x24, 0x20, 0x6a, 0x5d, 0xfc, 0xd2, 0xab, 0xef, 0x8f, 0x54, + 0xd8, 0x81, 0x14, 0x46, 0x9a, 0xe8, 0xfc, 0x64, 0x80, 0x77, 0x6a, 0x2c, 0x78, 0x4c, 0x11, 0xe4, + 0xe8, 0x4b, 0x84, 0x49, 0x64, 0x3e, 0x00, 0xb3, 0x0c, 0xe1, 0x16, 0xa2, 0x05, 0xe3, 0xae, 0x71, + 0x7f, 0xbe, 0xba, 0xda, 0x8b, 0xed, 0xa5, 0x33, 0x18, 0x7d, 0x5b, 0x71, 0xd4, 0xba, 0xe3, 0x6b, + 0x80, 0xe9, 0x81, 0x39, 0xd6, 0x6d, 0xb4, 0x04, 0xad, 0x70, 0x4d, 0x82, 0xd7, 0x7a, 0xb1, 0xbd, + 0xac, 0xc1, 0x3a, 0xe2, 0xf8, 0x29, 0xa8, 0x52, 0xfe, 0xee, 0xea, 0x7c, 0x5b, 0xb3, 0x7f, 0xb8, + 0x3a, 0xdf, 0x1e, 0x5d, 0x61, 0x53, 0x56, 0x53, 0x52, 0xec, 0x67, 0xe0, 0x76, 0xb6, 0x40, 0x1f, + 0xb1, 0x0e, 0xc1, 0x0c, 0x99, 0x55, 0xb0, 0x8c, 0xd1, 0x69, 0x5d, 0x52, 0xeb, 0xaa, 0x08, 0x55, + 0xb1, 0xd5, 0x8b, 0xed, 0xdb, 0xaa, 0x88, 0x1c, 0xc0, 0xf1, 0x97, 0x30, 0x3a, 0x3d, 0x14, 0x0b, + 0x32, 0x97, 0xf3, 0x8f, 0x01, 0x6e, 0xd5, 0x58, 0x50, 0x0b, 0x31, 0x9f, 0x46, 0xf8, 0x13, 0x30, + 0x0b, 0x23, 0xd2, 0xc5, 0x5c, 0xca, 0x5e, 0xd8, 0xd9, 0x74, 0xf5, 0x76, 0x88, 0x4d, 0x4d, 0x9a, + 0xc3, 0x7d, 0x4c, 0x42, 0x5c, 0x7d, 0xf7, 0x55, 0x6c, 0xcf, 0xf4, 0x33, 0x29, 0x9a, 0xe3, 0x6b, + 0xbe, 0xf9, 0x05, 0x58, 0x8a, 0x42, 0xcc, 0x0f, 0xc9, 0xa3, 0x56, 0x8b, 0x22, 0xc6, 0x0a, 0xd7, + 0xf3, 0x12, 0x44, 0xb8, 0xce, 0x49, 0x1d, 0x2a, 0x80, 0xe3, 0x67, 0x09, 0x95, 0x07, 0x39, 0x4f, + 0x37, 0x47, 0x7a, 0x2a, 0x38, 0xce, 0x2a, 0x58, 0xd6, 0x62, 0x13, 0x13, 0x9d, 0x7f, 0x95, 0x01, + 0xd5, 0x2e, 0xc5, 0x6f, 0xc7, 0x80, 0x7d, 0xb0, 0xdc, 0xe8, 0x52, 0xbc, 0x4f, 0x49, 0x94, 0xb5, + 0x60, 0xab, 0x17, 0xdb, 0x05, 0xc5, 0x11, 0x80, 0xfa, 0x11, 0x25, 0x51, 0xdf, 0x84, 0x3c, 0x69, + 0x42, 0x1b, 0x04, 0x4b, 0xdb, 0x20, 0x24, 0xa7, 0x36, 0xfc, 0xa1, 0xcf, 0xc1, 0x31, 0xc4, 0x01, + 0x7a, 0xd4, 0x8a, 0xc2, 0xa9, 0xdc, 0xf8, 0x10, 0xdc, 0x1c, 0x3c, 0x04, 0x2b, 0xbd, 0xd8, 0x5e, + 0x54, 0x48, 0xdd, 0x75, 0x2a, 0x6c, 0x96, 0xc1, 0xbc, 0x68, 0x48, 0x28, 0xf2, 0x6b, 0x95, 0xeb, + 0xbd, 0xd8, 0x5e, 0xe9, 0xf7, 0xaa, 0x0c, 0x39, 0xfe, 0x1c, 0x46, 0xa7, 0xb2, 0x8a, 0x49, 0x4f, + 0x8c, 0xac, 0xbb, 0xa4, 0xd8, 0x05, 0x75, 0x62, 0xfa, 0x52, 0x52, 0x95, 0x17, 0x06, 0x58, 0xaf, + 0xb1, 0xe0, 0x00, 0xf1, 0x2a, 0x3a, 0x22, 0x14, 0x1d, 0x20, 0xdc, 0x7a, 0x42, 0x48, 0xfb, 0x4d, + 0x68, 0xfd, 0x0c, 0x2c, 0x35, 0x09, 0xe6, 0x14, 0x36, 0xb9, 0xdc, 0x35, 0xad, 0xb7, 0xd0, 0x8b, + 0xed, 0x75, 0x85, 0xcf, 0x84, 0x1d, 0x7f, 0x31, 0x79, 0x16, 0x3b, 0x5a, 0xf9, 0x24, 0xa7, 0xfb, + 0xfe, 0x48, 0xdd, 0x0c, 0xf1, 0x52, 0x43, 0x4a, 0x11, 0xc8, 0xd2, 0x31, 0x21, 0x6d, 0xa7, 0x08, + 0xb6, 0x46, 0x69, 0x4c, 0x4d, 0xf8, 0xd9, 0x00, 0x6b, 0x0a, 0x20, 0x47, 0x40, 0x0d, 0x71, 0xd8, + 0x82, 0x1c, 0x4e, 0xe3, 0x81, 0x0f, 0xe6, 0x22, 0x4d, 0xd3, 0xfd, 0x7f, 0xa7, 0xdf, 0xff, 0xb8, + 0x9d, 0xf6, 0x7f, 0x92, 0xbb, 0xba, 0xa1, 0xcf, 0x80, 0x1e, 0x8d, 0x09, 0xd9, 0xf1, 0xd3, 0x3c, + 0x95, 0x85, 0x01, 0xc1, 0xce, 0x1d, 0xf0, 0xde, 0x88, 0x12, 0x53, 0x09, 0xf1, 0x35, 0xb0, 0x52, + 0x63, 0xc1, 0x3e, 0xa1, 0x4d, 0x74, 0x48, 0x21, 0x66, 0x47, 0x88, 0xbe, 0x9d, 0xd3, 0xeb, 0x83, + 0x35, 0xae, 0x0b, 0x18, 0x3e, 0xc1, 0x77, 0x7b, 0xb1, 0xbd, 0xa5, 0x78, 0x09, 0x28, 0x77, 0x8a, + 0x47, 0x91, 0xcd, 0xaf, 0xc0, 0x6a, 0xb2, 0xdc, 0x1f, 0x8b, 0x37, 0x64, 0xc6, 0x62, 0x2f, 0xb6, + 0xad, 0x5c, 0xc6, 0xc1, 0xd1, 0x38, 0x4c, 0xac, 0x3c, 0xcc, 0x35, 0xd2, 0x07, 0x23, 0x1b, 0xe9, + 0x48, 0x58, 0x59, 0x4a, 0xd8, 0x8e, 0x05, 0x0a, 0x79, 0x7f, 0x53, 0xf3, 0x7f, 0x37, 0xe4, 0xf8, + 0xf8, 0xba, 0xd3, 0x82, 0x1c, 0x3d, 0x95, 0x97, 0xa9, 0xb9, 0x07, 0xe6, 0x61, 0x97, 0x1f, 0x13, + 0x1a, 0xf2, 0x33, 0x6d, 0x7f, 0xe1, 0xcf, 0xdf, 0x4a, 0xeb, 0xda, 0x56, 0x5d, 0xcb, 0x01, 0xa7, + 0x21, 0x0e, 0xfc, 0x3e, 0xd4, 0xfc, 0x1c, 0xcc, 0xaa, 0xeb, 0x58, 0x6f, 0xc4, 0x96, 0x3b, 0xf2, + 0x6b, 0x43, 0xbd, 0xa5, 0x3a, 0x2f, 0xf6, 0xe2, 0xd7, 0xab, 0xf3, 0x6d, 0xc3, 0xd7, 0xb4, 0xca, + 0xae, 0x50, 0xd7, 0x4f, 0x28, 0x27, 0x44, 0x88, 0x39, 0xa2, 0xcd, 0x63, 0x18, 0xe2, 0xe7, 0x5d, + 0x44, 0x43, 0xc4, 0xbc, 0x5c, 0xb9, 0xce, 0x26, 0xd8, 0xc8, 0x2d, 0x25, 0xea, 0x76, 0x7e, 0xb9, + 0x05, 0xae, 0xd7, 0x58, 0x60, 0x3e, 0x07, 0x0b, 0x83, 0x1f, 0x05, 0x1f, 0xb9, 0xff, 0xf7, 0x19, + 0xe4, 0x66, 0x6f, 0x68, 0x6b, 0x77, 0x1a, 0x74, 0x7a, 0x9f, 0x3f, 0x03, 0x37, 0xe4, 0x3d, 0x7c, + 0x6f, 0x2c, 0x5b, 0xc0, 0xac, 0xd2, 0x44, 0xb0, 0xc1, 0xec, 0xf2, 0x92, 0x1b, 0x9f, 0x5d, 0xc0, + 0x26, 0xc8, 0x3e, 0x78, 0x7f, 0x48, 0xbb, 0x06, 0xee, 0x8e, 0x09, 0xec, 0xea, 0xa3, 0x27, 0xb1, + 0x6b, 0x78, 0x98, 0x9b, 0x2f, 0x0d, 0xb0, 0x32, 0x34, 0xc4, 0xca, 0x63, 0x53, 0xe5, 0x29, 0xd6, + 0xa7, 0x53, 0x53, 0xd2, 0x12, 0xbe, 0x37, 0xc0, 0xea, 0xf0, 0x65, 0xb2, 0x33, 0x49, 0xc2, 0x2c, + 0xc7, 0xaa, 0x4c, 0xcf, 0x49, 0xab, 0x38, 0x05, 0x4b, 0xd9, 0x49, 0xe8, 0x8e, 0x4d, 0x96, 0xc1, + 0x5b, 0x7b, 0xd3, 0xe1, 0xd3, 0x17, 0x73, 0xb0, 0x98, 0x99, 0x02, 0xe3, 0x7b, 0x66, 0x10, 0x6e, + 0x7d, 0x3c, 0x15, 0x3c, 0x79, 0xab, 0x75, 0xf3, 0xa5, 0x98, 0x00, 0xd5, 0xa7, 0xaf, 0x2e, 0x8a, + 0xc6, 0xeb, 0x8b, 0xa2, 0xf1, 0xf7, 0x45, 0xd1, 0xf8, 0xf1, 0xb2, 0x38, 0xf3, 0xfa, 0xb2, 0x38, + 0xf3, 0xd7, 0x65, 0x71, 0xe6, 0x9b, 0xbd, 0x20, 0xe4, 0xc7, 0xdd, 0x86, 0xdb, 0x24, 0x91, 0x87, + 0x51, 0x97, 0x53, 0x82, 0x4b, 0x84, 0x06, 0xc9, 0x6f, 0xef, 0x64, 0xd7, 0x7b, 0x91, 0x9d, 0x7e, + 0xfc, 0xac, 0x83, 0x58, 0x63, 0x56, 0xfe, 0x49, 0xf0, 0xf0, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xab, 0x2e, 0xa9, 0x6f, 0x19, 0x0d, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/tokenfactory/types/v1beta1/params.pb.go b/x/tokenfactory/types/v1beta1/params.pb.go new file mode 100644 index 000000000..2cf60f11d --- /dev/null +++ b/x/tokenfactory/types/v1beta1/params.pb.go @@ -0,0 +1,442 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: osmosis/tokenfactory/v1beta1/params.proto + +package v1beta1 + +import ( + fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + + _ "github.com/cosmos/cosmos-proto" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Params defines the parameters for the tokenfactory module. +type Params struct { + // DenomCreationFee defines the fee to be charged on the creation of a new + // denom. The fee is drawn from the MsgCreateDenom's sender account, and + // transferred to the community pool. + DenomCreationFee github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=denom_creation_fee,json=denomCreationFee,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"denom_creation_fee" yaml:"denom_creation_fee"` + // DenomCreationGasConsume defines the gas cost for creating a new denom. + // This is intended as a spam deterrence mechanism. + // + // See: https://github.com/CosmWasm/token-factory/issues/11 + DenomCreationGasConsume uint64 `protobuf:"varint,2,opt,name=denom_creation_gas_consume,json=denomCreationGasConsume,proto3" json:"denom_creation_gas_consume,omitempty" yaml:"denom_creation_gas_consume"` + // FeeCollectorAddress is the address where fees collected from denom creation + // are sent to + FeeCollectorAddress string `protobuf:"bytes,3,opt,name=fee_collector_address,json=feeCollectorAddress,proto3" json:"fee_collector_address,omitempty"` +} + +func (m *Params) Reset() { *m = Params{} } +func (m *Params) String() string { return proto.CompactTextString(m) } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_cc8299d306f3ff47, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.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 *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func (m *Params) GetDenomCreationFee() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.DenomCreationFee + } + return nil +} + +func (m *Params) GetDenomCreationGasConsume() uint64 { + if m != nil { + return m.DenomCreationGasConsume + } + return 0 +} + +func (m *Params) GetFeeCollectorAddress() string { + if m != nil { + return m.FeeCollectorAddress + } + return "" +} + +func init() { + proto.RegisterType((*Params)(nil), "osmosis.tokenfactory.v1beta1.Params") +} + +func init() { + proto.RegisterFile("osmosis/tokenfactory/v1beta1/params.proto", fileDescriptor_cc8299d306f3ff47) +} + +var fileDescriptor_cc8299d306f3ff47 = []byte{ + // 376 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0xbd, 0x6e, 0xe2, 0x40, + 0x10, 0xf6, 0xc2, 0x09, 0xe9, 0x7c, 0xcd, 0xc9, 0x77, 0xa7, 0x03, 0x74, 0xb2, 0x39, 0x57, 0xa6, + 0xc0, 0x2b, 0x48, 0xaa, 0x14, 0x91, 0x82, 0xa5, 0xa4, 0x8a, 0x14, 0x51, 0x45, 0x69, 0xac, 0xb5, + 0x3d, 0x76, 0x2c, 0xf0, 0x0e, 0xf2, 0x2e, 0x28, 0xbc, 0x45, 0xaa, 0x3c, 0x44, 0xde, 0x21, 0x3d, + 0x25, 0x65, 0x2a, 0x27, 0x82, 0x37, 0xe0, 0x09, 0x22, 0xfc, 0x13, 0x41, 0x92, 0xca, 0x33, 0xf3, + 0x7d, 0xf3, 0xcd, 0xe7, 0x99, 0x55, 0xbb, 0x28, 0x12, 0x14, 0xb1, 0xa0, 0x12, 0xc7, 0xc0, 0x43, + 0xe6, 0x4b, 0x4c, 0x17, 0x74, 0xde, 0xf7, 0x40, 0xb2, 0x3e, 0x9d, 0xb2, 0x94, 0x25, 0xc2, 0x9e, + 0xa6, 0x28, 0x51, 0xfb, 0x57, 0x52, 0xed, 0x7d, 0xaa, 0x5d, 0x52, 0xdb, 0xba, 0x9f, 0xc3, 0xd4, + 0x63, 0x02, 0xde, 0xfb, 0x7d, 0x8c, 0x79, 0xd1, 0xdd, 0x6e, 0x15, 0xb8, 0x9b, 0x67, 0xb4, 0x48, + 0x4a, 0xe8, 0x77, 0x84, 0x11, 0x16, 0xf5, 0x5d, 0x54, 0x54, 0xcd, 0xa7, 0x9a, 0xda, 0xb8, 0xca, + 0xe7, 0x6b, 0x0f, 0x44, 0xd5, 0x02, 0xe0, 0x98, 0xb8, 0x7e, 0x0a, 0x4c, 0xc6, 0xc8, 0xdd, 0x10, + 0xa0, 0x49, 0x3a, 0x75, 0xeb, 0xc7, 0xa0, 0x65, 0x97, 0x62, 0xbb, 0xc9, 0x95, 0x1d, 0xdb, 0xc1, + 0x98, 0x0f, 0x2f, 0x97, 0x99, 0xa1, 0x6c, 0x33, 0xa3, 0xb5, 0x60, 0xc9, 0xe4, 0xc4, 0xfc, 0x2c, + 0x61, 0x3e, 0xbe, 0x18, 0x56, 0x14, 0xcb, 0xdb, 0x99, 0x67, 0xfb, 0x98, 0x94, 0xb6, 0xca, 0x4f, + 0x4f, 0x04, 0x63, 0x2a, 0x17, 0x53, 0x10, 0xb9, 0x9a, 0x18, 0xfd, 0xcc, 0x05, 0x9c, 0xb2, 0xff, + 0x1c, 0x40, 0x0b, 0xd5, 0xf6, 0x07, 0xd1, 0x88, 0x09, 0xd7, 0x47, 0x2e, 0x66, 0x09, 0x34, 0x6b, + 0x1d, 0x62, 0x7d, 0x1b, 0x76, 0x97, 0x99, 0x41, 0xb6, 0x99, 0xf1, 0xff, 0x4b, 0x13, 0x7b, 0x7c, + 0x73, 0xf4, 0xf7, 0x60, 0xc0, 0x05, 0x13, 0x4e, 0x81, 0x68, 0x03, 0xf5, 0x4f, 0x08, 0xe0, 0xfa, + 0x38, 0x99, 0xc0, 0x6e, 0xed, 0x2e, 0x0b, 0x82, 0x14, 0x84, 0x68, 0xd6, 0x3b, 0xc4, 0xfa, 0x3e, + 0xfa, 0x15, 0x02, 0x38, 0x15, 0x76, 0x56, 0x40, 0xc3, 0xeb, 0xe5, 0x5a, 0x27, 0xab, 0xb5, 0x4e, + 0x5e, 0xd7, 0x3a, 0xb9, 0xdf, 0xe8, 0xca, 0x6a, 0xa3, 0x2b, 0xcf, 0x1b, 0x5d, 0xb9, 0x39, 0xdd, + 0xfb, 0x63, 0x0e, 0x33, 0x99, 0x22, 0xef, 0x61, 0x1a, 0x55, 0x31, 0x9d, 0x1f, 0xd3, 0xbb, 0xc3, + 0xf7, 0x90, 0x6f, 0xa1, 0xba, 0xaa, 0xd7, 0xc8, 0x0f, 0x74, 0xf4, 0x16, 0x00, 0x00, 0xff, 0xff, + 0xc4, 0x5e, 0x24, 0x25, 0x3c, 0x02, 0x00, 0x00, +} + +func (m *Params) 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 *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.FeeCollectorAddress) > 0 { + i -= len(m.FeeCollectorAddress) + copy(dAtA[i:], m.FeeCollectorAddress) + i = encodeVarintParams(dAtA, i, uint64(len(m.FeeCollectorAddress))) + i-- + dAtA[i] = 0x1a + } + if m.DenomCreationGasConsume != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.DenomCreationGasConsume)) + i-- + dAtA[i] = 0x10 + } + if len(m.DenomCreationFee) > 0 { + for iNdEx := len(m.DenomCreationFee) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.DenomCreationFee[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintParams(dAtA []byte, offset int, v uint64) int { + offset -= sovParams(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.DenomCreationFee) > 0 { + for _, e := range m.DenomCreationFee { + l = e.Size() + n += 1 + l + sovParams(uint64(l)) + } + } + if m.DenomCreationGasConsume != 0 { + n += 1 + sovParams(uint64(m.DenomCreationGasConsume)) + } + l = len(m.FeeCollectorAddress) + if l > 0 { + n += 1 + l + sovParams(uint64(l)) + } + return n +} + +func sovParams(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozParams(x uint64) (n int) { + return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) 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 ErrIntOverflowParams + } + 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: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + 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 DenomCreationFee", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DenomCreationFee = append(m.DenomCreationFee, types.Coin{}) + if err := m.DenomCreationFee[len(m.DenomCreationFee)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DenomCreationGasConsume", wireType) + } + m.DenomCreationGasConsume = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DenomCreationGasConsume |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FeeCollectorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FeeCollectorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipParams(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowParams + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowParams + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowParams + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthParams + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupParams + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthParams + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowParams = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group") +) From 2251fdd8915e07a9aa1ab71befe07bf716ffb0f3 Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Tue, 18 Jun 2024 23:59:49 -0400 Subject: [PATCH 02/23] Fix tests --- x/tokenfactory/keeper/before_send_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/tokenfactory/keeper/before_send_test.go b/x/tokenfactory/keeper/before_send_test.go index 0378ab92f..965c7308d 100644 --- a/x/tokenfactory/keeper/before_send_test.go +++ b/x/tokenfactory/keeper/before_send_test.go @@ -73,7 +73,7 @@ func (suite *KeeperTestSuite) TestTrackBeforeSendWasm() { // Whitelist the hook params := types.DefaultParams() - params.WhitelistedHooks = []*types.HookWhitelist{{DenomCreator: senderAddress.String(), CodeID: codeID}} + params.WhitelistedHooks = []*types.HookWhitelist{{DenomCreator: suite.TestAccs[0].String(), CodeID: codeID}} err = suite.GetNeutronZoneApp(suite.ChainA).TokenFactoryKeeper.SetParams(suite.ChainA.GetContext(), params) suite.Require().NoError(err) From c07f8238f530e90b7377d01e5d6c350a28004714 Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Tue, 18 Jun 2024 23:59:58 -0400 Subject: [PATCH 03/23] Add note on weird TF code --- x/tokenfactory/types/tx.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x/tokenfactory/types/tx.go b/x/tokenfactory/types/tx.go index 3925b0b5a..8b908d852 100644 --- a/x/tokenfactory/types/tx.go +++ b/x/tokenfactory/types/tx.go @@ -32,5 +32,11 @@ func (msg *MsgUpdateParams) Validate() error { return errorsmod.Wrap(err, "authority is invalid") } + // TODO: This is inconsistent. Per Params.Validate() an empty creator address is valid as long as + // DenomCreationFee is nil. But This check fails if FeeCollectorAddress is unset. + if _, err := sdk.AccAddressFromBech32(msg.Params.FeeCollectorAddress); err != nil { + return errorsmod.Wrap(err, "fee_collector_address is invalid") + } + return msg.Params.Validate() } From 209c6b3c57d9a4dbcf7f60fcda7a002dc76fb35c Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Wed, 19 Jun 2024 00:47:46 -0400 Subject: [PATCH 04/23] Block adding non-whitelisted hooks --- x/tokenfactory/keeper/before_send.go | 4 ++-- x/tokenfactory/keeper/msg_server.go | 9 +++++++++ x/tokenfactory/keeper/params.go | 10 +++++----- x/tokenfactory/types/errors.go | 23 ++++++++++++----------- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/x/tokenfactory/keeper/before_send.go b/x/tokenfactory/keeper/before_send.go index 81e25796e..014140d0d 100644 --- a/x/tokenfactory/keeper/before_send.go +++ b/x/tokenfactory/keeper/before_send.go @@ -99,8 +99,8 @@ func (k Keeper) callBeforeSendListener(ctx context.Context, from, to sdk.AccAddr return err } - // Do not invoke hook if denom is not whitelisted and `from` is a module - if !k.isHookWhitelisted(c, coin.Denom, cwAddr) { + // Do not invoke hook if denom is not whitelisted + if err := k.AssertIsHookWhitelisted(c, coin.Denom, cwAddr); err != nil { return nil } diff --git a/x/tokenfactory/keeper/msg_server.go b/x/tokenfactory/keeper/msg_server.go index 39006c3ad..d708a8488 100644 --- a/x/tokenfactory/keeper/msg_server.go +++ b/x/tokenfactory/keeper/msg_server.go @@ -246,6 +246,15 @@ func (server msgServer) SetBeforeSendHook(goCtx context.Context, msg *types.MsgS return nil, types.ErrUnauthorized } + // If we are not removing a hook make sure it has been already whitelisted + if msg.ContractAddr != "" { + // msg.ContractAddr has already been validated + cwAddr := sdk.MustAccAddressFromBech32(msg.ContractAddr) + if err := server.Keeper.AssertIsHookWhitelisted(ctx, msg.Denom, cwAddr); err != nil { + return nil, err + } + } + err = server.Keeper.setBeforeSendHook(ctx, msg.Denom, msg.ContractAddr) if err != nil { return nil, err diff --git a/x/tokenfactory/keeper/params.go b/x/tokenfactory/keeper/params.go index e9e124f7b..4c97b9018 100644 --- a/x/tokenfactory/keeper/params.go +++ b/x/tokenfactory/keeper/params.go @@ -30,23 +30,23 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error { return nil } -func (k Keeper) isHookWhitelisted(ctx sdk.Context, denom string, contractAddress sdk.AccAddress) bool { +func (k Keeper) AssertIsHookWhitelisted(ctx sdk.Context, denom string, contractAddress sdk.AccAddress) error { contractInfo := k.contractKeeper.GetContractInfo(ctx, contractAddress) if contractInfo == nil { - return false + return types.ErrBeforeSendHookNotWhitelisted.Wrapf("contract with address (%s) does not exist", contractAddress.String()) } codeID := contractInfo.CodeID whitelistedHooks := k.GetParams(ctx).WhitelistedHooks denomCreator, _, err := types.DeconstructDenom(denom) if err != nil { - return false + return types.ErrBeforeSendHookNotWhitelisted.Wrapf("invalid denom: %s", denom) } for _, hook := range whitelistedHooks { if hook.CodeID == codeID && hook.DenomCreator == denomCreator { - return true + return nil } } - return false + return types.ErrBeforeSendHookNotWhitelisted.Wrapf("no whitelist for contract with codeID (%d) and denomCreator (%s) ", codeID, denomCreator) } diff --git a/x/tokenfactory/types/errors.go b/x/tokenfactory/types/errors.go index c20e41980..91c2c2f13 100644 --- a/x/tokenfactory/types/errors.go +++ b/x/tokenfactory/types/errors.go @@ -8,15 +8,16 @@ import ( // x/tokenfactory module sentinel errors var ( - ErrDenomExists = errorsmod.Register(ModuleName, 2, "attempting to create a denom that already exists (has bank metadata)") - ErrUnauthorized = errorsmod.Register(ModuleName, 3, "unauthorized account") - ErrInvalidDenom = errorsmod.Register(ModuleName, 4, "invalid denom") - ErrInvalidCreator = errorsmod.Register(ModuleName, 5, "invalid creator") - ErrInvalidAuthorityMetadata = errorsmod.Register(ModuleName, 6, "invalid authority metadata") - ErrInvalidGenesis = errorsmod.Register(ModuleName, 7, "invalid genesis") - ErrSubdenomTooLong = errorsmod.Register(ModuleName, 8, fmt.Sprintf("subdenom too long, max length is %d bytes", MaxSubdenomLength)) - ErrCreatorTooLong = errorsmod.Register(ModuleName, 9, fmt.Sprintf("creator too long, max length is %d bytes", MaxCreatorLength)) - ErrDenomDoesNotExist = errorsmod.Register(ModuleName, 10, "denom does not exist") - ErrBurnFromModuleAccount = errorsmod.Register(ModuleName, 11, "burning from Module Account is not allowed") - ErrTrackBeforeSendOutOfGas = errorsmod.Register(ModuleName, 12, "gas meter hit maximum limit") + ErrDenomExists = errorsmod.Register(ModuleName, 2, "attempting to create a denom that already exists (has bank metadata)") + ErrUnauthorized = errorsmod.Register(ModuleName, 3, "unauthorized account") + ErrInvalidDenom = errorsmod.Register(ModuleName, 4, "invalid denom") + ErrInvalidCreator = errorsmod.Register(ModuleName, 5, "invalid creator") + ErrInvalidAuthorityMetadata = errorsmod.Register(ModuleName, 6, "invalid authority metadata") + ErrInvalidGenesis = errorsmod.Register(ModuleName, 7, "invalid genesis") + ErrSubdenomTooLong = errorsmod.Register(ModuleName, 8, fmt.Sprintf("subdenom too long, max length is %d bytes", MaxSubdenomLength)) + ErrCreatorTooLong = errorsmod.Register(ModuleName, 9, fmt.Sprintf("creator too long, max length is %d bytes", MaxCreatorLength)) + ErrDenomDoesNotExist = errorsmod.Register(ModuleName, 10, "denom does not exist") + ErrBurnFromModuleAccount = errorsmod.Register(ModuleName, 11, "burning from Module Account is not allowed") + ErrTrackBeforeSendOutOfGas = errorsmod.Register(ModuleName, 12, "gas meter hit maximum limit") + ErrBeforeSendHookNotWhitelisted = errorsmod.Register(ModuleName, 13, "beforeSendHook is not whitelisted") ) From 1b2cdecc81f7f79a92f5d6a01440f55e1780a9bd Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Wed, 19 Jun 2024 01:04:48 -0400 Subject: [PATCH 05/23] Refactor + add more tests --- x/tokenfactory/keeper/before_send_test.go | 176 ++++++++++++---------- 1 file changed, 100 insertions(+), 76 deletions(-) diff --git a/x/tokenfactory/keeper/before_send_test.go b/x/tokenfactory/keeper/before_send_test.go index 965c7308d..e5e92ef83 100644 --- a/x/tokenfactory/keeper/before_send_test.go +++ b/x/tokenfactory/keeper/before_send_test.go @@ -2,7 +2,6 @@ package keeper_test import ( "encoding/json" - "fmt" "os" "cosmossdk.io/math" @@ -12,80 +11,105 @@ import ( "github.com/neutron-org/neutron/v4/x/tokenfactory/types" ) -func (suite *KeeperTestSuite) TestTrackBeforeSendWasm() { - for _, tc := range []struct { - name string - wasmFile string - }{ - { - name: "Test bank hook tracking contract ", - // https://github.com/neutron-org/neutron-dev-contracts/tree/feat/balance-tracker-contract/contracts/balance-tracker - wasmFile: "./testdata/balance_tracker.wasm", +func (suite *KeeperTestSuite) initBalanceTrackContract(denom string) (sdk.AccAddress, uint64, string) { + senderAddress := suite.ChainA.SenderAccounts[0].SenderAccount.GetAddress() + suite.TopUpWallet(suite.ChainA.GetContext(), senderAddress, suite.TestAccs[0]) + + // https://github.com/neutron-org/neutron-dev-contracts/tree/feat/balance-tracker-contract/contracts/balance-tracker + wasmFile := "./testdata/balance_tracker.wasm" + + // load wasm file + wasmCode, err := os.ReadFile(wasmFile) + suite.Require().NoError(err) + + // create new denom + res, err := suite.msgServer.CreateDenom(suite.ChainA.GetContext(), types.NewMsgCreateDenom(suite.TestAccs[0].String(), denom)) + suite.Require().NoError(err) + factoryDenom := res.GetNewTokenDenom() + + // instantiate wasm code + tokenFactoryModuleAddr := suite.GetNeutronZoneApp(suite.ChainA).AccountKeeper.GetModuleAddress("tokenfactory") + contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(suite.GetNeutronZoneApp(suite.ChainA).WasmKeeper) + codeID, _, err := contractKeeper.Create(suite.ChainA.GetContext(), suite.TestAccs[0], wasmCode, nil) + suite.Require().NoError(err) + initMsg, _ := json.Marshal( + map[string]interface{}{ + "tracked_denom": factoryDenom, + "tokenfactory_module_address": tokenFactoryModuleAddr, }, - } { - suite.Run(fmt.Sprintf("Case %s", tc.name), func() { - // setup test - suite.Setup() - - senderAddress := suite.ChainA.SenderAccounts[0].SenderAccount.GetAddress() - suite.TopUpWallet(suite.ChainA.GetContext(), senderAddress, suite.TestAccs[0]) - - // load wasm file - wasmCode, err := os.ReadFile(tc.wasmFile) - suite.Require().NoError(err) - - // create new denom - res, err := suite.msgServer.CreateDenom(suite.ChainA.GetContext(), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "testdenom")) - suite.Require().NoError(err, "test: %v", tc.name) - factoryDenom := res.GetNewTokenDenom() - - // instantiate wasm code - tokenFactoryModuleAddr := suite.GetNeutronZoneApp(suite.ChainA).AccountKeeper.GetModuleAddress("tokenfactory") - contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(suite.GetNeutronZoneApp(suite.ChainA).WasmKeeper) - codeID, _, err := contractKeeper.Create(suite.ChainA.GetContext(), suite.TestAccs[0], wasmCode, nil) - suite.Require().NoError(err, "test: %v", tc.name) - initMsg, _ := json.Marshal( - map[string]interface{}{ - "tracked_denom": factoryDenom, - "tokenfactory_module_address": tokenFactoryModuleAddr, - }, - ) - cosmwasmAddress, _, err := contractKeeper.Instantiate( - suite.ChainA.GetContext(), codeID, suite.TestAccs[0], suite.TestAccs[0], initMsg, "", sdk.NewCoins(), - ) - suite.Require().NoError(err, "test: %v", tc.name) - - // set beforesend hook to the new denom - _, err = suite.msgServer.SetBeforeSendHook(suite.ChainA.GetContext(), types.NewMsgSetBeforeSendHook(suite.TestAccs[0].String(), factoryDenom, cosmwasmAddress.String())) - suite.Require().NoError(err, "test: %v", tc.name) - - tokenToSend := sdk.NewCoin(factoryDenom, math.NewInt(100)) - - // mint tokens - _, err = suite.msgServer.Mint(suite.ChainA.GetContext(), types.NewMsgMint(suite.TestAccs[0].String(), tokenToSend)) - suite.Require().NoError(err) - - queryResp, err := suite.GetNeutronZoneApp(suite.ChainA).WasmKeeper.QuerySmart(suite.ChainA.GetContext(), cosmwasmAddress, []byte(`{"total_supply_at":{}}`)) - suite.Require().NoError(err) - - // Contract has not been called because it is not whitelisted - suite.Require().Equal("\"0\"", string(queryResp)) - - // Whitelist the hook - params := types.DefaultParams() - params.WhitelistedHooks = []*types.HookWhitelist{{DenomCreator: suite.TestAccs[0].String(), CodeID: codeID}} - err = suite.GetNeutronZoneApp(suite.ChainA).TokenFactoryKeeper.SetParams(suite.ChainA.GetContext(), params) - suite.Require().NoError(err) - - // mint tokens again - _, err = suite.msgServer.Mint(suite.ChainA.GetContext(), types.NewMsgMint(suite.TestAccs[0].String(), tokenToSend)) - suite.Require().NoError(err) - - queryResp, err = suite.GetNeutronZoneApp(suite.ChainA).WasmKeeper.QuerySmart(suite.ChainA.GetContext(), cosmwasmAddress, []byte(`{"total_supply_at":{}}`)) - suite.Require().NoError(err) - - // Whitelisted contract has now been called - suite.Require().Equal("\"100\"", string(queryResp)) - }) - } + ) + cosmwasmAddress, _, err := contractKeeper.Instantiate( + suite.ChainA.GetContext(), codeID, suite.TestAccs[0], suite.TestAccs[0], initMsg, "", sdk.NewCoins(), + ) + suite.Require().NoError(err) + + return cosmwasmAddress, codeID, factoryDenom +} + +func (suite *KeeperTestSuite) TestTrackBeforeSendWasm() { + suite.Setup() + + cosmwasmAddress, codeID, factoryDenom := suite.initBalanceTrackContract("testdenom") + + // Whitelist the hook + params := types.DefaultParams() + params.WhitelistedHooks = []*types.HookWhitelist{{DenomCreator: suite.TestAccs[0].String(), CodeID: codeID}} + err := suite.GetNeutronZoneApp(suite.ChainA).TokenFactoryKeeper.SetParams(suite.ChainA.GetContext(), params) + suite.Require().NoError(err) + + // set beforeSendHook for the new denom + _, err = suite.msgServer.SetBeforeSendHook(suite.ChainA.GetContext(), types.NewMsgSetBeforeSendHook(suite.TestAccs[0].String(), factoryDenom, cosmwasmAddress.String())) + suite.Require().NoError(err) + + tokenToSend := sdk.NewCoin(factoryDenom, math.NewInt(100)) + + // mint tokens + _, err = suite.msgServer.Mint(suite.ChainA.GetContext(), types.NewMsgMint(suite.TestAccs[0].String(), tokenToSend)) + suite.Require().NoError(err) + + queryResp, err := suite.GetNeutronZoneApp(suite.ChainA).WasmKeeper.QuerySmart(suite.ChainA.GetContext(), cosmwasmAddress, []byte(`{"total_supply_at":{}}`)) + // Whitelisted contract is called correctly + suite.Require().Equal("\"100\"", string(queryResp)) +} + +func (suite *KeeperTestSuite) TestAddNonWhitelistedHooksFails() { + suite.Setup() + + cosmwasmAddress, _, factoryDenom := suite.initBalanceTrackContract("testdenom") + + // WHEN to set beforeSendHook + _, err := suite.msgServer.SetBeforeSendHook(suite.ChainA.GetContext(), types.NewMsgSetBeforeSendHook(suite.TestAccs[0].String(), factoryDenom, cosmwasmAddress.String())) + // THEN fails with BeforeSendHookNotWhitelisted + suite.Require().ErrorIs(err, types.ErrBeforeSendHookNotWhitelisted) +} + +func (suite *KeeperTestSuite) TestNonWhitelistedHooksNotCalled() { + suite.Setup() + + cosmwasmAddress, codeID, factoryDenom := suite.initBalanceTrackContract("testdenom") + + // Whitelist the hook first so it can be added + params := types.DefaultParams() + params.WhitelistedHooks = []*types.HookWhitelist{{DenomCreator: suite.TestAccs[0].String(), CodeID: codeID}} + err := suite.GetNeutronZoneApp(suite.ChainA).TokenFactoryKeeper.SetParams(suite.ChainA.GetContext(), params) + suite.Require().NoError(err) + + // set beforeSendHook for the new denom + _, err = suite.msgServer.SetBeforeSendHook(suite.ChainA.GetContext(), types.NewMsgSetBeforeSendHook(suite.TestAccs[0].String(), factoryDenom, cosmwasmAddress.String())) + suite.Require().NoError(err) + + // Remove whitelist for the hook + params = types.DefaultParams() + err = suite.GetNeutronZoneApp(suite.ChainA).TokenFactoryKeeper.SetParams(suite.ChainA.GetContext(), params) + suite.Require().NoError(err) + + tokenToSend := sdk.NewCoin(factoryDenom, math.NewInt(100)) + + // mint tokens + _, err = suite.msgServer.Mint(suite.ChainA.GetContext(), types.NewMsgMint(suite.TestAccs[0].String(), tokenToSend)) + suite.Require().NoError(err) + + queryResp, err := suite.GetNeutronZoneApp(suite.ChainA).WasmKeeper.QuerySmart(suite.ChainA.GetContext(), cosmwasmAddress, []byte(`{"total_supply_at":{}}`)) + // Whitelisted contract is not called + suite.Require().Equal("\"0\"", string(queryResp)) } From 5469b7918f54139f6bd0bc91c679c618d5a4763a Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Wed, 19 Jun 2024 01:39:34 -0400 Subject: [PATCH 06/23] add migration --- x/tokenfactory/keeper/migrations.go | 22 ++++++++ x/tokenfactory/migrations/v2/store.go | 62 ++++++++++++++++++++++ x/tokenfactory/migrations/v2/store_test.go | 52 ++++++++++++++++++ x/tokenfactory/module.go | 4 ++ x/tokenfactory/types/constants.go | 2 +- 5 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 x/tokenfactory/keeper/migrations.go create mode 100644 x/tokenfactory/migrations/v2/store.go create mode 100644 x/tokenfactory/migrations/v2/store_test.go diff --git a/x/tokenfactory/keeper/migrations.go b/x/tokenfactory/keeper/migrations.go new file mode 100644 index 000000000..12f76d00d --- /dev/null +++ b/x/tokenfactory/keeper/migrations.go @@ -0,0 +1,22 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + v2 "github.com/neutron-org/neutron/v4/x/tokenfactory/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.cdc, m.keeper.storeKey) +} diff --git a/x/tokenfactory/migrations/v2/store.go b/x/tokenfactory/migrations/v2/store.go new file mode 100644 index 000000000..72e69bb65 --- /dev/null +++ b/x/tokenfactory/migrations/v2/store.go @@ -0,0 +1,62 @@ +package v2 + +import ( + "errors" + + storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/neutron-org/neutron/v4/x/tokenfactory/types" + v1beta1types "github.com/neutron-org/neutron/v4/x/tokenfactory/types/v1beta1" +) + +// MigrateStore performs in-place store migrations. +// The migration adds the new tokenfactory params WhitelistedHooks +func MigrateStore(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.StoreKey) error { + return migrateParams(ctx, cdc, storeKey) + +} + +var WhitelistedHooks = []*types.HookWhitelist{ + + { // xASTRO balances tracker + CodeID: 944, + DenomCreator: "neutron1zlf3hutsa4qnmue53lz2tfxrutp8y2e3rj4nkghg3rupgl4mqy8s5jgxsn", + }, + { // NFA.zoneV1 + CodeID: 1265, + DenomCreator: "neutron1pwjn3tsumm3j7v7clzqhjsaukv4tdjlclhdytawhet68fwlz84fqcrdyf5", + }, +} + +func migrateParams(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.StoreKey) error { + ctx.Logger().Info("Migrating tokenfactory params...") + + // fetch old params + store := ctx.KVStore(storeKey) + bz := store.Get(types.ParamsKey) + if bz == nil { + return errors.New("cannot fetch tokenfactory params from KV store") + } + var oldParams v1beta1types.Params + cdc.MustUnmarshal(bz, &oldParams) + + // add new param values + newParams := types.Params{ + DenomCreationFee: oldParams.DenomCreationFee, + DenomCreationGasConsume: oldParams.DenomCreationGasConsume, + FeeCollectorAddress: oldParams.FeeCollectorAddress, + WhitelistedHooks: WhitelistedHooks, + } + + // set params + bz, err := cdc.Marshal(&newParams) + if err != nil { + return err + } + store.Set(types.ParamsKey, bz) + + ctx.Logger().Info("Finished migrating tokenfactory params") + + return nil +} diff --git a/x/tokenfactory/migrations/v2/store_test.go b/x/tokenfactory/migrations/v2/store_test.go new file mode 100644 index 000000000..91c52ade1 --- /dev/null +++ b/x/tokenfactory/migrations/v2/store_test.go @@ -0,0 +1,52 @@ +package v2_test + +import ( + "testing" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/neutron-org/neutron/v4/testutil" + v2 "github.com/neutron-org/neutron/v4/x/tokenfactory/migrations/v2" + "github.com/neutron-org/neutron/v4/x/tokenfactory/types" + "github.com/neutron-org/neutron/v4/x/tokenfactory/types/v1beta1" + "github.com/stretchr/testify/suite" +) + +type V3DexMigrationTestSuite struct { + testutil.IBCConnectionTestSuite +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(V3DexMigrationTestSuite)) +} + +func (suite *V3DexMigrationTestSuite) TestParamsUpgrade() { + var ( + app = suite.GetNeutronZoneApp(suite.ChainA) + storeKey = app.GetKey(types.StoreKey) + ctx = suite.ChainA.GetContext() + cdc = app.AppCodec() + ) + + // Write old state + oldParams := v1beta1.Params{ + DenomCreationFee: sdk.NewCoins(sdk.NewCoin("untrn", math.OneInt())), + DenomCreationGasConsume: types.DefaultDenomCreationGasConsume, + FeeCollectorAddress: "test_addr", + } + store := ctx.KVStore(storeKey) + bz, err := cdc.Marshal(&oldParams) + suite.Require().NoError(err) + + store.Set(types.ParamsKey, bz) + + // Run migration + suite.NoError(v2.MigrateStore(ctx, cdc, storeKey)) + + // Check params are correct + newParams := app.TokenFactoryKeeper.GetParams(ctx) + suite.Require().EqualValues(oldParams.DenomCreationFee, newParams.DenomCreationFee) + suite.Require().EqualValues(newParams.DenomCreationGasConsume, newParams.DenomCreationGasConsume) + suite.Require().EqualValues(newParams.FeeCollectorAddress, newParams.FeeCollectorAddress) + suite.Require().EqualValues(newParams.WhitelistedHooks, v2.WhitelistedHooks) +} diff --git a/x/tokenfactory/module.go b/x/tokenfactory/module.go index 559495ff2..0f09e8260 100644 --- a/x/tokenfactory/module.go +++ b/x/tokenfactory/module.go @@ -135,6 +135,10 @@ func (AppModule) QuerierRoute() string { return types.QuerierRoute } func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterQueryServer(cfg.QueryServer(), am.keeper) types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) + m := keeper.NewMigrator(am.keeper) + if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil { + panic(fmt.Sprintf("failed to migrate x/tokenfactory from version 1 to 1: %v", err)) + } } // RegisterInvariants registers the tokenfactory module's invariants. diff --git a/x/tokenfactory/types/constants.go b/x/tokenfactory/types/constants.go index b68bbb99a..066fcad70 100644 --- a/x/tokenfactory/types/constants.go +++ b/x/tokenfactory/types/constants.go @@ -1,5 +1,5 @@ package types -const ConsensusVersion = 1 +const ConsensusVersion = 2 var TrackBeforeSendGasLimit = uint64(100_000) From 448149e2bbeae08ce3ecabc3f56895c7529f71b9 Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Wed, 19 Jun 2024 01:42:55 -0400 Subject: [PATCH 07/23] lint --- x/tokenfactory/keeper/before_send_test.go | 2 ++ x/tokenfactory/migrations/v2/store.go | 3 +-- x/tokenfactory/migrations/v2/store_test.go | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/x/tokenfactory/keeper/before_send_test.go b/x/tokenfactory/keeper/before_send_test.go index e5e92ef83..bf3c7150a 100644 --- a/x/tokenfactory/keeper/before_send_test.go +++ b/x/tokenfactory/keeper/before_send_test.go @@ -68,6 +68,7 @@ func (suite *KeeperTestSuite) TestTrackBeforeSendWasm() { suite.Require().NoError(err) queryResp, err := suite.GetNeutronZoneApp(suite.ChainA).WasmKeeper.QuerySmart(suite.ChainA.GetContext(), cosmwasmAddress, []byte(`{"total_supply_at":{}}`)) + suite.Require().NoError(err) // Whitelisted contract is called correctly suite.Require().Equal("\"100\"", string(queryResp)) } @@ -110,6 +111,7 @@ func (suite *KeeperTestSuite) TestNonWhitelistedHooksNotCalled() { suite.Require().NoError(err) queryResp, err := suite.GetNeutronZoneApp(suite.ChainA).WasmKeeper.QuerySmart(suite.ChainA.GetContext(), cosmwasmAddress, []byte(`{"total_supply_at":{}}`)) + suite.Require().NoError(err) // Whitelisted contract is not called suite.Require().Equal("\"0\"", string(queryResp)) } diff --git a/x/tokenfactory/migrations/v2/store.go b/x/tokenfactory/migrations/v2/store.go index 72e69bb65..ac9ae1a29 100644 --- a/x/tokenfactory/migrations/v2/store.go +++ b/x/tokenfactory/migrations/v2/store.go @@ -6,6 +6,7 @@ import ( storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/neutron-org/neutron/v4/x/tokenfactory/types" v1beta1types "github.com/neutron-org/neutron/v4/x/tokenfactory/types/v1beta1" ) @@ -14,11 +15,9 @@ import ( // The migration adds the new tokenfactory params WhitelistedHooks func MigrateStore(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.StoreKey) error { return migrateParams(ctx, cdc, storeKey) - } var WhitelistedHooks = []*types.HookWhitelist{ - { // xASTRO balances tracker CodeID: 944, DenomCreator: "neutron1zlf3hutsa4qnmue53lz2tfxrutp8y2e3rj4nkghg3rupgl4mqy8s5jgxsn", diff --git a/x/tokenfactory/migrations/v2/store_test.go b/x/tokenfactory/migrations/v2/store_test.go index 91c52ade1..1985ff107 100644 --- a/x/tokenfactory/migrations/v2/store_test.go +++ b/x/tokenfactory/migrations/v2/store_test.go @@ -5,11 +5,12 @@ import ( "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" + "github.com/neutron-org/neutron/v4/testutil" v2 "github.com/neutron-org/neutron/v4/x/tokenfactory/migrations/v2" "github.com/neutron-org/neutron/v4/x/tokenfactory/types" "github.com/neutron-org/neutron/v4/x/tokenfactory/types/v1beta1" - "github.com/stretchr/testify/suite" ) type V3DexMigrationTestSuite struct { From 5b971b1a83ce1712880f57eb353be62108846fe1 Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Wed, 19 Jun 2024 15:21:50 -0400 Subject: [PATCH 08/23] add migration to remove non-whitelisted tf hooks --- x/tokenfactory/keeper/migrations.go | 2 +- x/tokenfactory/migrations/v2/store.go | 55 ++++++++++++++++- x/tokenfactory/migrations/v2/store_test.go | 72 +++++++++++++++++++++- 3 files changed, 125 insertions(+), 4 deletions(-) diff --git a/x/tokenfactory/keeper/migrations.go b/x/tokenfactory/keeper/migrations.go index 12f76d00d..fa10d45ae 100644 --- a/x/tokenfactory/keeper/migrations.go +++ b/x/tokenfactory/keeper/migrations.go @@ -18,5 +18,5 @@ func NewMigrator(keeper Keeper) Migrator { // Migrate1to2 migrates from version 1 to 2. func (m Migrator) Migrate1to2(ctx sdk.Context) error { - return v2.MigrateStore(ctx, m.keeper.cdc, m.keeper.storeKey) + return v2.MigrateStore(ctx, m.keeper.cdc, m.keeper.storeKey, m.keeper) } diff --git a/x/tokenfactory/migrations/v2/store.go b/x/tokenfactory/migrations/v2/store.go index ac9ae1a29..e81e4d90a 100644 --- a/x/tokenfactory/migrations/v2/store.go +++ b/x/tokenfactory/migrations/v2/store.go @@ -2,6 +2,9 @@ package v2 import ( "errors" + "strings" + + "cosmossdk.io/store/prefix" storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" @@ -11,10 +14,22 @@ import ( v1beta1types "github.com/neutron-org/neutron/v4/x/tokenfactory/types/v1beta1" ) +type TokenFactoryKeeper interface { + AssertIsHookWhitelisted(ctx sdk.Context, denom string, contractAddress sdk.AccAddress) error +} + // MigrateStore performs in-place store migrations. // The migration adds the new tokenfactory params WhitelistedHooks -func MigrateStore(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.StoreKey) error { - return migrateParams(ctx, cdc, storeKey) +func MigrateStore(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.StoreKey, keeper TokenFactoryKeeper) error { + // NOTE: this must happen first since the migrateHooks relies on the new params + if err := migrateParams(ctx, cdc, storeKey); err != nil { + return err + } + if err := migrateHooks(ctx, cdc, storeKey, keeper); err != nil { + return err + } + + return nil } var WhitelistedHooks = []*types.HookWhitelist{ @@ -59,3 +74,39 @@ func migrateParams(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.S return nil } + +func migrateHooks(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.StoreKey, keeper TokenFactoryKeeper) error { + ctx.Logger().Info("Migrating tokenfactory hooks...") + + // get hook store + store := prefix.NewStore(ctx.KVStore(storeKey), []byte(types.DenomsPrefixKey)) + iterator := storetypes.KVStorePrefixIterator(store, []byte{}) + + for ; iterator.Valid(); iterator.Next() { + keyParts := strings.Split(string(iterator.Key()), types.KeySeparator) + + // Hooks and authorityMetadata are in the same store we only care about the hooks + if keyParts[2] == types.BeforeSendHookAddressPrefixKey { + denom := keyParts[1] + contractAddr, err := sdk.AccAddressFromBech32(string(iterator.Value())) + if err != nil { + return errors.New("cannot parse hook contract address") + } + + err = keeper.AssertIsHookWhitelisted(ctx, denom, contractAddr) + if err != nil { + // If hook is not whitelisted delete it + store.Delete(iterator.Key()) + } + } + } + + err := iterator.Close() + if err != nil { + return err + } + + ctx.Logger().Info("Finished migrating tokenfactory hooks") + + return nil +} diff --git a/x/tokenfactory/migrations/v2/store_test.go b/x/tokenfactory/migrations/v2/store_test.go index 1985ff107..9f62318ab 100644 --- a/x/tokenfactory/migrations/v2/store_test.go +++ b/x/tokenfactory/migrations/v2/store_test.go @@ -1,9 +1,12 @@ package v2_test import ( + "encoding/json" + "os" "testing" "cosmossdk.io/math" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" @@ -42,7 +45,7 @@ func (suite *V3DexMigrationTestSuite) TestParamsUpgrade() { store.Set(types.ParamsKey, bz) // Run migration - suite.NoError(v2.MigrateStore(ctx, cdc, storeKey)) + suite.NoError(v2.MigrateStore(ctx, cdc, storeKey, app.TokenFactoryKeeper)) // Check params are correct newParams := app.TokenFactoryKeeper.GetParams(ctx) @@ -51,3 +54,70 @@ func (suite *V3DexMigrationTestSuite) TestParamsUpgrade() { suite.Require().EqualValues(newParams.FeeCollectorAddress, newParams.FeeCollectorAddress) suite.Require().EqualValues(newParams.WhitelistedHooks, v2.WhitelistedHooks) } + +func (suite *V3DexMigrationTestSuite) TestHooksUpgrade() { + var ( + app = suite.GetNeutronZoneApp(suite.ChainA) + storeKey = app.GetKey(types.StoreKey) + ctx = suite.ChainA.GetContext() + cdc = app.AppCodec() + addr1 = suite.ChainA.SenderAccounts[0].SenderAccount.GetAddress() + addr2 = suite.ChainA.SenderAccounts[1].SenderAccount.GetAddress() + ) + + wasmFile := "../../keeper/testdata/balance_tracker.wasm" + wasmCode, err := os.ReadFile(wasmFile) + suite.Require().NoError(err) + + // Setup contract + contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(suite.GetNeutronZoneApp(suite.ChainA).WasmKeeper) + codeID, _, err := contractKeeper.Create(ctx, addr1, wasmCode, nil) + tokenFactoryModuleAddr := app.AccountKeeper.GetModuleAddress(types.ModuleName) + initMsg, _ := json.Marshal( + map[string]interface{}{ + "tracked_denom": "test_denom", + "tokenfactory_module_address": tokenFactoryModuleAddr, + }, + ) + cwAddress, _, err := contractKeeper.Instantiate(ctx, codeID, addr1, addr1, initMsg, "", sdk.NewCoins()) + suite.Require().NoError(err) + cwAddressStr := cwAddress.String() + + // Add Denoms and hooks + factoryDenom1, err := app.TokenFactoryKeeper.CreateDenom(ctx, addr1.String(), "test1") + suite.Require().NoError(err) + store := app.TokenFactoryKeeper.GetDenomPrefixStore(ctx, factoryDenom1) + store.Set([]byte(types.BeforeSendHookAddressPrefixKey), []byte(cwAddressStr)) + + factoryDenom2, err := app.TokenFactoryKeeper.CreateDenom(ctx, addr2.String(), "test2") + suite.Require().NoError(err) + store = app.TokenFactoryKeeper.GetDenomPrefixStore(ctx, factoryDenom2) + store.Set([]byte(types.BeforeSendHookAddressPrefixKey), []byte(cwAddressStr)) + + factoryDenom3, err := app.TokenFactoryKeeper.CreateDenom(ctx, addr2.String(), "test3") + suite.Require().NoError(err) + store = app.TokenFactoryKeeper.GetDenomPrefixStore(ctx, factoryDenom2) + store.Set([]byte(types.BeforeSendHookAddressPrefixKey), []byte(cwAddressStr)) + + // Include the hook we want to whitelist in the params migration + v2.WhitelistedHooks = []*types.HookWhitelist{ + { + CodeID: codeID, + DenomCreator: addr1.String(), + }, + } + + // Run migration + suite.NoError(v2.MigrateStore(ctx, cdc, storeKey, app.TokenFactoryKeeper)) + + // The whitelisted hook is still there + hook1 := app.TokenFactoryKeeper.GetBeforeSendHook(ctx, factoryDenom1) + suite.Assert().Equal(cwAddressStr, hook1) + + //The non whitelisted hooks have been removed + hook2 := app.TokenFactoryKeeper.GetBeforeSendHook(ctx, factoryDenom2) + suite.Assert().Equal("", hook2) + hook3 := app.TokenFactoryKeeper.GetBeforeSendHook(ctx, factoryDenom3) + suite.Assert().Equal("", hook3) + +} From d4b551cb2cc77aab3508e2d8b5f5750608264e95 Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Wed, 19 Jun 2024 15:26:21 -0400 Subject: [PATCH 09/23] lint --- x/tokenfactory/migrations/v2/store.go | 6 +++--- x/tokenfactory/migrations/v2/store_test.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x/tokenfactory/migrations/v2/store.go b/x/tokenfactory/migrations/v2/store.go index e81e4d90a..2eb5f5f8d 100644 --- a/x/tokenfactory/migrations/v2/store.go +++ b/x/tokenfactory/migrations/v2/store.go @@ -25,7 +25,7 @@ func MigrateStore(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.St if err := migrateParams(ctx, cdc, storeKey); err != nil { return err } - if err := migrateHooks(ctx, cdc, storeKey, keeper); err != nil { + if err := migrateHooks(ctx, storeKey, keeper); err != nil { return err } @@ -75,7 +75,7 @@ func migrateParams(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.S return nil } -func migrateHooks(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.StoreKey, keeper TokenFactoryKeeper) error { +func migrateHooks(ctx sdk.Context, storeKey storetypes.StoreKey, keeper TokenFactoryKeeper) error { ctx.Logger().Info("Migrating tokenfactory hooks...") // get hook store @@ -85,7 +85,7 @@ func migrateHooks(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.St for ; iterator.Valid(); iterator.Next() { keyParts := strings.Split(string(iterator.Key()), types.KeySeparator) - // Hooks and authorityMetadata are in the same store we only care about the hooks + // Hooks and authorityMetadata are in the same store, we only care about the hooks if keyParts[2] == types.BeforeSendHookAddressPrefixKey { denom := keyParts[1] contractAddr, err := sdk.AccAddressFromBech32(string(iterator.Value())) diff --git a/x/tokenfactory/migrations/v2/store_test.go b/x/tokenfactory/migrations/v2/store_test.go index 9f62318ab..19c1f5072 100644 --- a/x/tokenfactory/migrations/v2/store_test.go +++ b/x/tokenfactory/migrations/v2/store_test.go @@ -72,6 +72,7 @@ func (suite *V3DexMigrationTestSuite) TestHooksUpgrade() { // Setup contract contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(suite.GetNeutronZoneApp(suite.ChainA).WasmKeeper) codeID, _, err := contractKeeper.Create(ctx, addr1, wasmCode, nil) + suite.Require().NoError(err) tokenFactoryModuleAddr := app.AccountKeeper.GetModuleAddress(types.ModuleName) initMsg, _ := json.Marshal( map[string]interface{}{ @@ -114,10 +115,9 @@ func (suite *V3DexMigrationTestSuite) TestHooksUpgrade() { hook1 := app.TokenFactoryKeeper.GetBeforeSendHook(ctx, factoryDenom1) suite.Assert().Equal(cwAddressStr, hook1) - //The non whitelisted hooks have been removed + // The non whitelisted hooks have been removed hook2 := app.TokenFactoryKeeper.GetBeforeSendHook(ctx, factoryDenom2) suite.Assert().Equal("", hook2) hook3 := app.TokenFactoryKeeper.GetBeforeSendHook(ctx, factoryDenom3) suite.Assert().Equal("", hook3) - } From 71ee07e8ece2fd3824a54abba44011ab0c3964e9 Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Wed, 19 Jun 2024 15:45:16 -0400 Subject: [PATCH 10/23] misc review fixes --- proto/osmosis/tokenfactory/params.proto | 5 +- x/tokenfactory/keeper/before_send_test.go | 4 +- x/tokenfactory/migrations/v2/store.go | 2 +- x/tokenfactory/migrations/v2/store_test.go | 2 +- x/tokenfactory/module.go | 2 +- x/tokenfactory/types/params.go | 8 +- x/tokenfactory/types/params.pb.go | 121 +++++++++++---------- 7 files changed, 73 insertions(+), 71 deletions(-) diff --git a/proto/osmosis/tokenfactory/params.proto b/proto/osmosis/tokenfactory/params.proto index 604da3956..ef7a36f6d 100644 --- a/proto/osmosis/tokenfactory/params.proto +++ b/proto/osmosis/tokenfactory/params.proto @@ -7,7 +7,7 @@ import "gogoproto/gogo.proto"; option go_package = "github.com/neutron-org/neutron/v4/x/tokenfactory/types"; -message HookWhitelist { +message WhitelistedHook { uint64 code_id = 1 [(gogoproto.customname) = "CodeID"]; string denom_creator = 2; } @@ -35,5 +35,6 @@ message Params { // FeeCollectorAddress is the address where fees collected from denom creation // are sent to string fee_collector_address = 3; - repeated HookWhitelist whitelisted_hooks = 4; + // HookWhitelist is the list of hooks which are allowed to be added and executed + repeated WhitelistedHook whitelisted_hooks = 4; } diff --git a/x/tokenfactory/keeper/before_send_test.go b/x/tokenfactory/keeper/before_send_test.go index bf3c7150a..cd1def71d 100644 --- a/x/tokenfactory/keeper/before_send_test.go +++ b/x/tokenfactory/keeper/before_send_test.go @@ -53,7 +53,7 @@ func (suite *KeeperTestSuite) TestTrackBeforeSendWasm() { // Whitelist the hook params := types.DefaultParams() - params.WhitelistedHooks = []*types.HookWhitelist{{DenomCreator: suite.TestAccs[0].String(), CodeID: codeID}} + params.WhitelistedHooks = []*types.WhitelistedHook{{DenomCreator: suite.TestAccs[0].String(), CodeID: codeID}} err := suite.GetNeutronZoneApp(suite.ChainA).TokenFactoryKeeper.SetParams(suite.ChainA.GetContext(), params) suite.Require().NoError(err) @@ -91,7 +91,7 @@ func (suite *KeeperTestSuite) TestNonWhitelistedHooksNotCalled() { // Whitelist the hook first so it can be added params := types.DefaultParams() - params.WhitelistedHooks = []*types.HookWhitelist{{DenomCreator: suite.TestAccs[0].String(), CodeID: codeID}} + params.WhitelistedHooks = []*types.WhitelistedHook{{DenomCreator: suite.TestAccs[0].String(), CodeID: codeID}} err := suite.GetNeutronZoneApp(suite.ChainA).TokenFactoryKeeper.SetParams(suite.ChainA.GetContext(), params) suite.Require().NoError(err) diff --git a/x/tokenfactory/migrations/v2/store.go b/x/tokenfactory/migrations/v2/store.go index 2eb5f5f8d..408317c17 100644 --- a/x/tokenfactory/migrations/v2/store.go +++ b/x/tokenfactory/migrations/v2/store.go @@ -32,7 +32,7 @@ func MigrateStore(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.St return nil } -var WhitelistedHooks = []*types.HookWhitelist{ +var WhitelistedHooks = []*types.WhitelistedHook{ { // xASTRO balances tracker CodeID: 944, DenomCreator: "neutron1zlf3hutsa4qnmue53lz2tfxrutp8y2e3rj4nkghg3rupgl4mqy8s5jgxsn", diff --git a/x/tokenfactory/migrations/v2/store_test.go b/x/tokenfactory/migrations/v2/store_test.go index 19c1f5072..b65b99cba 100644 --- a/x/tokenfactory/migrations/v2/store_test.go +++ b/x/tokenfactory/migrations/v2/store_test.go @@ -101,7 +101,7 @@ func (suite *V3DexMigrationTestSuite) TestHooksUpgrade() { store.Set([]byte(types.BeforeSendHookAddressPrefixKey), []byte(cwAddressStr)) // Include the hook we want to whitelist in the params migration - v2.WhitelistedHooks = []*types.HookWhitelist{ + v2.WhitelistedHooks = []*types.WhitelistedHook{ { CodeID: codeID, DenomCreator: addr1.String(), diff --git a/x/tokenfactory/module.go b/x/tokenfactory/module.go index 0f09e8260..c0a2322a3 100644 --- a/x/tokenfactory/module.go +++ b/x/tokenfactory/module.go @@ -137,7 +137,7 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) m := keeper.NewMigrator(am.keeper) if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil { - panic(fmt.Sprintf("failed to migrate x/tokenfactory from version 1 to 1: %v", err)) + panic(fmt.Sprintf("failed to migrate x/tokenfactory from version 1 to 2: %v", err)) } } diff --git a/x/tokenfactory/types/params.go b/x/tokenfactory/types/params.go index 06c1f76aa..8dcd4a029 100644 --- a/x/tokenfactory/types/params.go +++ b/x/tokenfactory/types/params.go @@ -17,7 +17,7 @@ var ( DefaultDenomCreationFee sdk.Coins DefaultDenomCreationGasConsume uint64 DefaultFeeCollectorAddress = "" - DefaultWhitelistedHooks = []*HookWhitelist{} + DefaultWhitelistedHooks = []*WhitelistedHook{} ) // ParamKeyTable the param key table for tokenfactory module. @@ -25,7 +25,7 @@ func ParamKeyTable() paramtypes.KeyTable { return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) } -func NewParams(denomCreationFee sdk.Coins, denomCreationGasConsume uint64, feeCollectorAddress string, whitelistedHooks []*HookWhitelist) Params { +func NewParams(denomCreationFee sdk.Coins, denomCreationGasConsume uint64, feeCollectorAddress string, whitelistedHooks []*WhitelistedHook) Params { return Params{ DenomCreationFee: denomCreationFee, DenomCreationGasConsume: denomCreationGasConsume, @@ -115,7 +115,7 @@ func validateFeeCollectorAddress(i interface{}) error { } func validateWhitelistedHooks(i interface{}) error { - hooks, ok := i.([]*HookWhitelist) + hooks, ok := i.([]*WhitelistedHook) if !ok { return fmt.Errorf("invalid parameter type: %T", i) } @@ -124,7 +124,7 @@ func validateWhitelistedHooks(i interface{}) error { for _, hook := range hooks { hookStr := hook.String() if seenHooks[hookStr] { - return fmt.Errorf("duplicate whitelisted hook: %#v", hook) + return fmt.Errorf("duplicate whitelisted hook: %s", hookStr) } seenHooks[hookStr] = true _, err := sdk.AccAddressFromBech32(hook.DenomCreator) diff --git a/x/tokenfactory/types/params.pb.go b/x/tokenfactory/types/params.pb.go index d05e3c72d..6138df390 100644 --- a/x/tokenfactory/types/params.pb.go +++ b/x/tokenfactory/types/params.pb.go @@ -27,23 +27,23 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -type HookWhitelist struct { +type WhitelistedHook struct { CodeID uint64 `protobuf:"varint,1,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` DenomCreator string `protobuf:"bytes,2,opt,name=denom_creator,json=denomCreator,proto3" json:"denom_creator,omitempty"` } -func (m *HookWhitelist) Reset() { *m = HookWhitelist{} } -func (m *HookWhitelist) String() string { return proto.CompactTextString(m) } -func (*HookWhitelist) ProtoMessage() {} -func (*HookWhitelist) Descriptor() ([]byte, []int) { +func (m *WhitelistedHook) Reset() { *m = WhitelistedHook{} } +func (m *WhitelistedHook) String() string { return proto.CompactTextString(m) } +func (*WhitelistedHook) ProtoMessage() {} +func (*WhitelistedHook) Descriptor() ([]byte, []int) { return fileDescriptor_09c297db7c49d1cf, []int{0} } -func (m *HookWhitelist) XXX_Unmarshal(b []byte) error { +func (m *WhitelistedHook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *HookWhitelist) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *WhitelistedHook) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_HookWhitelist.Marshal(b, m, deterministic) + return xxx_messageInfo_WhitelistedHook.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -53,26 +53,26 @@ func (m *HookWhitelist) XXX_Marshal(b []byte, deterministic bool) ([]byte, error return b[:n], nil } } -func (m *HookWhitelist) XXX_Merge(src proto.Message) { - xxx_messageInfo_HookWhitelist.Merge(m, src) +func (m *WhitelistedHook) XXX_Merge(src proto.Message) { + xxx_messageInfo_WhitelistedHook.Merge(m, src) } -func (m *HookWhitelist) XXX_Size() int { +func (m *WhitelistedHook) XXX_Size() int { return m.Size() } -func (m *HookWhitelist) XXX_DiscardUnknown() { - xxx_messageInfo_HookWhitelist.DiscardUnknown(m) +func (m *WhitelistedHook) XXX_DiscardUnknown() { + xxx_messageInfo_WhitelistedHook.DiscardUnknown(m) } -var xxx_messageInfo_HookWhitelist proto.InternalMessageInfo +var xxx_messageInfo_WhitelistedHook proto.InternalMessageInfo -func (m *HookWhitelist) GetCodeID() uint64 { +func (m *WhitelistedHook) GetCodeID() uint64 { if m != nil { return m.CodeID } return 0 } -func (m *HookWhitelist) GetDenomCreator() string { +func (m *WhitelistedHook) GetDenomCreator() string { if m != nil { return m.DenomCreator } @@ -92,8 +92,9 @@ type Params struct { DenomCreationGasConsume uint64 `protobuf:"varint,2,opt,name=denom_creation_gas_consume,json=denomCreationGasConsume,proto3" json:"denom_creation_gas_consume,omitempty" yaml:"denom_creation_gas_consume"` // FeeCollectorAddress is the address where fees collected from denom creation // are sent to - FeeCollectorAddress string `protobuf:"bytes,3,opt,name=fee_collector_address,json=feeCollectorAddress,proto3" json:"fee_collector_address,omitempty"` - WhitelistedHooks []*HookWhitelist `protobuf:"bytes,4,rep,name=whitelisted_hooks,json=whitelistedHooks,proto3" json:"whitelisted_hooks,omitempty"` + FeeCollectorAddress string `protobuf:"bytes,3,opt,name=fee_collector_address,json=feeCollectorAddress,proto3" json:"fee_collector_address,omitempty"` + // HookWhitelist is the list of hooks which are allowed to be added and executed + WhitelistedHooks []*WhitelistedHook `protobuf:"bytes,4,rep,name=whitelisted_hooks,json=whitelistedHooks,proto3" json:"whitelisted_hooks,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -150,7 +151,7 @@ func (m *Params) GetFeeCollectorAddress() string { return "" } -func (m *Params) GetWhitelistedHooks() []*HookWhitelist { +func (m *Params) GetWhitelistedHooks() []*WhitelistedHook { if m != nil { return m.WhitelistedHooks } @@ -158,46 +159,46 @@ func (m *Params) GetWhitelistedHooks() []*HookWhitelist { } func init() { - proto.RegisterType((*HookWhitelist)(nil), "osmosis.tokenfactory.HookWhitelist") + proto.RegisterType((*WhitelistedHook)(nil), "osmosis.tokenfactory.WhitelistedHook") proto.RegisterType((*Params)(nil), "osmosis.tokenfactory.Params") } func init() { proto.RegisterFile("osmosis/tokenfactory/params.proto", fileDescriptor_09c297db7c49d1cf) } var fileDescriptor_09c297db7c49d1cf = []byte{ - // 456 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0xb1, 0x8e, 0xd3, 0x40, - 0x10, 0x8d, 0x49, 0x14, 0xc4, 0xc2, 0x49, 0x87, 0x39, 0x84, 0x93, 0xc2, 0xce, 0x39, 0x4d, 0x28, - 0xce, 0xd6, 0x1d, 0x88, 0x82, 0x8e, 0x18, 0x01, 0x57, 0x20, 0x45, 0x6e, 0x10, 0x34, 0xd6, 0xc6, - 0x3b, 0x76, 0x56, 0x89, 0x77, 0x22, 0xef, 0xe6, 0x20, 0x5f, 0x01, 0x15, 0x1f, 0xc1, 0x97, 0xa4, - 0xbc, 0x92, 0xca, 0xa0, 0xe4, 0x0f, 0xee, 0x0b, 0x90, 0xd7, 0x8e, 0x70, 0xe0, 0x2a, 0xef, 0xbc, - 0x37, 0x33, 0x9e, 0xf7, 0x66, 0xc8, 0x29, 0xca, 0x0c, 0x25, 0x97, 0xbe, 0xc2, 0x39, 0x88, 0x84, - 0xc6, 0x0a, 0xf3, 0xb5, 0xbf, 0xa4, 0x39, 0xcd, 0xa4, 0xb7, 0xcc, 0x51, 0xa1, 0x79, 0x52, 0xa7, - 0x78, 0xcd, 0x94, 0xbe, 0x1d, 0x6b, 0xd8, 0x9f, 0x52, 0x09, 0xfe, 0xd5, 0xf9, 0x14, 0x14, 0x3d, - 0xf7, 0x63, 0xe4, 0xa2, 0xaa, 0xea, 0xf7, 0x2a, 0x3e, 0xd2, 0x91, 0x5f, 0x05, 0x35, 0x75, 0x92, - 0x62, 0x8a, 0x15, 0x5e, 0xbe, 0x2a, 0xd4, 0xfd, 0x48, 0x8e, 0xde, 0x21, 0xce, 0x3f, 0xcc, 0xb8, - 0x82, 0x05, 0x97, 0xca, 0x1c, 0x92, 0xbb, 0x31, 0x32, 0x88, 0x38, 0xb3, 0x8c, 0x81, 0x31, 0xea, - 0x8c, 0xc9, 0xb6, 0x70, 0xba, 0x01, 0x32, 0xb8, 0x7c, 0x1d, 0x76, 0x4b, 0xea, 0x92, 0x99, 0x43, - 0x72, 0xc4, 0x40, 0x60, 0x16, 0xc5, 0x39, 0x50, 0x85, 0xb9, 0x75, 0x67, 0x60, 0x8c, 0xee, 0x85, - 0x0f, 0x34, 0x18, 0x54, 0x98, 0xfb, 0xb5, 0x4d, 0xba, 0x13, 0x2d, 0xc9, 0xfc, 0x6e, 0x10, 0xb3, - 0x51, 0xc0, 0x51, 0x44, 0x09, 0x80, 0x65, 0x0c, 0xda, 0xa3, 0xfb, 0x17, 0x3d, 0xaf, 0x9e, 0xb3, - 0x14, 0xe5, 0xd5, 0xa2, 0xbc, 0x00, 0xb9, 0x18, 0xbf, 0xdf, 0x14, 0x4e, 0xeb, 0xa6, 0x70, 0x7a, - 0x6b, 0x9a, 0x2d, 0x5e, 0xba, 0xff, 0xb7, 0x70, 0x7f, 0xfc, 0x72, 0x46, 0x29, 0x57, 0xb3, 0xd5, - 0xd4, 0x8b, 0x31, 0xab, 0x15, 0xd7, 0x9f, 0x33, 0xc9, 0xe6, 0xbe, 0x5a, 0x2f, 0x41, 0xea, 0x6e, - 0x32, 0x3c, 0xfe, 0x3b, 0x1f, 0x47, 0xf1, 0x06, 0xc0, 0x4c, 0x48, 0xff, 0x9f, 0xa6, 0x29, 0x95, - 0x51, 0x8c, 0x42, 0xae, 0x32, 0xd0, 0xaa, 0x3a, 0xe3, 0xa7, 0x9b, 0xc2, 0x31, 0x6e, 0x0a, 0xe7, - 0xf4, 0xd6, 0x21, 0x1a, 0xf9, 0x6e, 0xf8, 0xe4, 0xe0, 0x07, 0x6f, 0xa9, 0x0c, 0x2a, 0xc6, 0xbc, - 0x20, 0x8f, 0x13, 0x80, 0x28, 0xc6, 0xc5, 0x02, 0xca, 0x4d, 0x46, 0x94, 0xb1, 0x1c, 0xa4, 0xb4, - 0xda, 0xda, 0xb8, 0x47, 0x09, 0x40, 0xb0, 0xe7, 0x5e, 0x55, 0x94, 0x39, 0x21, 0x0f, 0x3f, 0xef, - 0xd7, 0x02, 0x2c, 0x9a, 0x21, 0xce, 0xa5, 0xd5, 0xd1, 0x96, 0x0d, 0xbd, 0xdb, 0xae, 0xc3, 0x3b, - 0xd8, 0x64, 0x78, 0xdc, 0xa8, 0x2e, 0x19, 0x39, 0x9e, 0x6c, 0xb6, 0xb6, 0x71, 0xbd, 0xb5, 0x8d, - 0xdf, 0x5b, 0xdb, 0xf8, 0xb6, 0xb3, 0x5b, 0xd7, 0x3b, 0xbb, 0xf5, 0x73, 0x67, 0xb7, 0x3e, 0xbd, - 0x68, 0x78, 0x28, 0x60, 0xa5, 0x72, 0x14, 0x67, 0x98, 0xa7, 0xfb, 0xb7, 0x7f, 0xf5, 0xdc, 0xff, - 0x72, 0x78, 0xac, 0xda, 0xd7, 0x69, 0x57, 0x5f, 0xd1, 0xb3, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, - 0x1d, 0x23, 0x36, 0x33, 0xd1, 0x02, 0x00, 0x00, -} - -func (m *HookWhitelist) Marshal() (dAtA []byte, err error) { + // 457 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0xc1, 0x6e, 0xd3, 0x40, + 0x10, 0x8d, 0x49, 0x14, 0xc4, 0x02, 0xa2, 0x98, 0x22, 0x9c, 0x1c, 0xec, 0xd4, 0x15, 0x52, 0x38, + 0xd4, 0xab, 0x16, 0xc4, 0x81, 0x1b, 0x31, 0x02, 0x7a, 0x40, 0xaa, 0x7c, 0x41, 0x82, 0x83, 0xb5, + 0xf1, 0x8e, 0x9d, 0x55, 0xe2, 0x9d, 0xc8, 0xbb, 0x69, 0xc9, 0x5f, 0xc0, 0x85, 0x8f, 0xe0, 0x4b, + 0x72, 0xec, 0x91, 0x93, 0x41, 0xc9, 0x1f, 0xf4, 0x0b, 0x50, 0xd6, 0xae, 0x9a, 0x94, 0x9c, 0xbc, + 0xf3, 0xde, 0xcc, 0x78, 0xde, 0x9b, 0x21, 0x07, 0xa8, 0x72, 0x54, 0x42, 0x51, 0x8d, 0x63, 0x90, + 0x29, 0x4b, 0x34, 0x16, 0x73, 0x3a, 0x65, 0x05, 0xcb, 0x55, 0x30, 0x2d, 0x50, 0xa3, 0xbd, 0x5f, + 0xa7, 0x04, 0x9b, 0x29, 0x5d, 0x37, 0x31, 0x30, 0x1d, 0x32, 0x05, 0xf4, 0xfc, 0x78, 0x08, 0x9a, + 0x1d, 0xd3, 0x04, 0x85, 0xac, 0xaa, 0xba, 0x9d, 0x8a, 0x8f, 0x4d, 0x44, 0xab, 0xa0, 0xa6, 0xf6, + 0x33, 0xcc, 0xb0, 0xc2, 0xd7, 0xaf, 0x0a, 0xf5, 0xbf, 0x92, 0x47, 0x9f, 0x47, 0x42, 0xc3, 0x44, + 0x28, 0x0d, 0xfc, 0x23, 0xe2, 0xd8, 0x3e, 0x24, 0x77, 0x13, 0xe4, 0x10, 0x0b, 0xee, 0x58, 0x3d, + 0xab, 0xdf, 0x1a, 0x90, 0x65, 0xe9, 0xb5, 0x43, 0xe4, 0x70, 0xfa, 0x2e, 0x6a, 0xaf, 0xa9, 0x53, + 0x6e, 0x1f, 0x92, 0x87, 0x1c, 0x24, 0xe6, 0x71, 0x52, 0x00, 0xd3, 0x58, 0x38, 0x77, 0x7a, 0x56, + 0xff, 0x5e, 0xf4, 0xc0, 0x80, 0x61, 0x85, 0xf9, 0x3f, 0x9a, 0xa4, 0x7d, 0x66, 0x44, 0xd9, 0x3f, + 0x2d, 0x62, 0x6f, 0x14, 0x08, 0x94, 0x71, 0x0a, 0xe0, 0x58, 0xbd, 0x66, 0xff, 0xfe, 0x49, 0x27, + 0xa8, 0x27, 0x5d, 0xcb, 0x0a, 0x6a, 0x59, 0x41, 0x88, 0x42, 0x0e, 0x3e, 0x2d, 0x4a, 0xaf, 0x71, + 0x55, 0x7a, 0x9d, 0x39, 0xcb, 0x27, 0x6f, 0xfc, 0xff, 0x5b, 0xf8, 0xbf, 0xfe, 0x78, 0xfd, 0x4c, + 0xe8, 0xd1, 0x6c, 0x18, 0x24, 0x98, 0xd7, 0x9a, 0xeb, 0xcf, 0x91, 0xe2, 0x63, 0xaa, 0xe7, 0x53, + 0x50, 0xa6, 0x9b, 0x8a, 0xf6, 0x6e, 0xe6, 0x13, 0x28, 0xdf, 0x03, 0xd8, 0x29, 0xe9, 0xde, 0x6a, + 0x9a, 0x31, 0x15, 0x27, 0x28, 0xd5, 0x2c, 0x07, 0xa3, 0xaa, 0x35, 0x78, 0xb1, 0x28, 0x3d, 0xeb, + 0xaa, 0xf4, 0x0e, 0x76, 0x0e, 0xb1, 0x91, 0xef, 0x47, 0xcf, 0xb6, 0x7e, 0xf0, 0x81, 0xa9, 0xb0, + 0x62, 0xec, 0x13, 0xf2, 0x34, 0x05, 0x88, 0x13, 0x9c, 0x4c, 0x60, 0xbd, 0xcb, 0x98, 0x71, 0x5e, + 0x80, 0x52, 0x4e, 0xd3, 0x18, 0xf7, 0x24, 0x05, 0x08, 0xaf, 0xb9, 0xb7, 0x15, 0x65, 0x47, 0xe4, + 0xf1, 0xc5, 0xcd, 0x72, 0xe2, 0x11, 0xe2, 0x58, 0x39, 0x2d, 0x63, 0xd9, 0xf3, 0x60, 0xd7, 0x7d, + 0x04, 0xb7, 0x76, 0x19, 0xed, 0x5d, 0x6c, 0x03, 0x6a, 0x70, 0xb6, 0x58, 0xba, 0xd6, 0xe5, 0xd2, + 0xb5, 0xfe, 0x2e, 0x5d, 0xeb, 0xfb, 0xca, 0x6d, 0x5c, 0xae, 0xdc, 0xc6, 0xef, 0x95, 0xdb, 0xf8, + 0xf2, 0x7a, 0xc3, 0x45, 0x09, 0x33, 0x5d, 0xa0, 0x3c, 0xc2, 0x22, 0xbb, 0x7e, 0xd3, 0xf3, 0x57, + 0xf4, 0xdb, 0xf6, 0xc1, 0x1a, 0x67, 0x87, 0x6d, 0x73, 0x49, 0x2f, 0xff, 0x05, 0x00, 0x00, 0xff, + 0xff, 0x0e, 0x4e, 0x8c, 0xba, 0xd5, 0x02, 0x00, 0x00, +} + +func (m *WhitelistedHook) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -207,12 +208,12 @@ func (m *HookWhitelist) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *HookWhitelist) MarshalTo(dAtA []byte) (int, error) { +func (m *WhitelistedHook) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *HookWhitelist) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *WhitelistedHook) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -306,7 +307,7 @@ func encodeVarintParams(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *HookWhitelist) Size() (n int) { +func (m *WhitelistedHook) Size() (n int) { if m == nil { return 0 } @@ -356,7 +357,7 @@ func sovParams(x uint64) (n int) { func sozParams(x uint64) (n int) { return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *HookWhitelist) Unmarshal(dAtA []byte) error { +func (m *WhitelistedHook) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -379,10 +380,10 @@ func (m *HookWhitelist) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: HookWhitelist: wiretype end group for non-group") + return fmt.Errorf("proto: WhitelistedHook: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: HookWhitelist: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: WhitelistedHook: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -600,7 +601,7 @@ func (m *Params) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.WhitelistedHooks = append(m.WhitelistedHooks, &HookWhitelist{}) + m.WhitelistedHooks = append(m.WhitelistedHooks, &WhitelistedHook{}) if err := m.WhitelistedHooks[len(m.WhitelistedHooks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } From a6eae66545df6e128da2c7cac81ff4c1c02deb7b Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Wed, 19 Jun 2024 15:47:19 -0400 Subject: [PATCH 11/23] regen swagger --- docs/static/swagger.yaml | 69 +++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/docs/static/swagger.yaml b/docs/static/swagger.yaml index 3a5fa1ee6..a10ae098e 100644 --- a/docs/static/swagger.yaml +++ b/docs/static/swagger.yaml @@ -18637,17 +18637,7 @@ definitions: type: array type: object type: object - osmosis.tokenfactory.v1beta1.DenomAuthorityMetadata: - description: |- - DenomAuthorityMetadata specifies metadata for addresses that have specific - capabilities over a token factory denom. Right now there is only one Admin - permission, but is planned to be extended to the future. - properties: - Admin: - title: Can be empty for no admin, or a valid osmosis address - type: string - type: object - osmosis.tokenfactory.v1beta1.Params: + osmosis.tokenfactory.Params: description: Params defines the parameters for the tokenfactory module. properties: denom_creation_fee: @@ -18686,6 +18676,37 @@ definitions: are sent to type: string + whitelisted_hooks: + items: + properties: + code_id: + format: uint64 + type: string + denom_creator: + type: string + type: object + title: >- + HookWhitelist is the list of hooks which are allowed to be added and + executed + type: array + type: object + osmosis.tokenfactory.WhitelistedHook: + properties: + code_id: + format: uint64 + type: string + denom_creator: + type: string + type: object + osmosis.tokenfactory.v1beta1.DenomAuthorityMetadata: + description: |- + DenomAuthorityMetadata specifies metadata for addresses that have specific + capabilities over a token factory denom. Right now there is only one Admin + permission, but is planned to be extended to the future. + properties: + Admin: + title: Can be empty for no admin, or a valid osmosis address + type: string type: object osmosis.tokenfactory.v1beta1.QueryBeforeSendHookAddressResponse: description: |- @@ -18774,6 +18795,19 @@ definitions: are sent to type: string + whitelisted_hooks: + items: + properties: + code_id: + format: uint64 + type: string + denom_creator: + type: string + type: object + title: >- + HookWhitelist is the list of hooks which are allowed to be added + and executed + type: array type: object type: object packetforward.v1.Params: @@ -43742,6 +43776,19 @@ paths: are sent to type: string + whitelisted_hooks: + items: + properties: + code_id: + format: uint64 + type: string + denom_creator: + type: string + type: object + title: >- + HookWhitelist is the list of hooks which are allowed to be + added and executed + type: array type: object type: object default: From b5d02d424ccd054e95d2ed2be292bb868258e63a Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Thu, 20 Jun 2024 12:56:29 -0400 Subject: [PATCH 12/23] PR review fixes --- x/tokenfactory/keeper/before_send.go | 26 +++++++++++++++++++++++++- x/tokenfactory/keeper/params.go | 21 --------------------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/x/tokenfactory/keeper/before_send.go b/x/tokenfactory/keeper/before_send.go index 014140d0d..ea592478b 100644 --- a/x/tokenfactory/keeper/before_send.go +++ b/x/tokenfactory/keeper/before_send.go @@ -68,6 +68,27 @@ func (k Keeper) Hooks() Hooks { return Hooks{k} } +func (k Keeper) AssertIsHookWhitelisted(ctx sdk.Context, denom string, contractAddress sdk.AccAddress) error { + contractInfo := k.contractKeeper.GetContractInfo(ctx, contractAddress) + if contractInfo == nil { + return types.ErrBeforeSendHookNotWhitelisted.Wrapf("contract with address (%s) does not exist", contractAddress.String()) + } + codeID := contractInfo.CodeID + whitelistedHooks := k.GetParams(ctx).WhitelistedHooks + denomCreator, _, err := types.DeconstructDenom(denom) + if err != nil { + return types.ErrBeforeSendHookNotWhitelisted.Wrapf("invalid denom: %s", denom) + } + + for _, hook := range whitelistedHooks { + if hook.CodeID == codeID && hook.DenomCreator == denomCreator { + return nil + } + } + + return types.ErrBeforeSendHookNotWhitelisted.Wrapf("no whitelist for contract with codeID (%d) and denomCreator (%s) ", codeID, denomCreator) +} + // TrackBeforeSend calls the before send listener contract suppresses any errors func (h Hooks) TrackBeforeSend(ctx context.Context, from, to sdk.AccAddress, amount sdk.Coins) { _ = h.k.callBeforeSendListener(ctx, from, to, amount, false) @@ -100,8 +121,11 @@ func (k Keeper) callBeforeSendListener(ctx context.Context, from, to sdk.AccAddr } // Do not invoke hook if denom is not whitelisted + // NOTE: hooks must already be whitelisted before they can be added, so under normal operation this check should never fail. + // It is here as an emergency override if we want to shutoff a hook. We do not return the error because once it is removed from the whitelist + // a hook should not be able to block a send. if err := k.AssertIsHookWhitelisted(c, coin.Denom, cwAddr); err != nil { - return nil + continue } var msgBz []byte diff --git a/x/tokenfactory/keeper/params.go b/x/tokenfactory/keeper/params.go index 4c97b9018..4faa1764d 100644 --- a/x/tokenfactory/keeper/params.go +++ b/x/tokenfactory/keeper/params.go @@ -29,24 +29,3 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error { store.Set(types.ParamsKey, bz) return nil } - -func (k Keeper) AssertIsHookWhitelisted(ctx sdk.Context, denom string, contractAddress sdk.AccAddress) error { - contractInfo := k.contractKeeper.GetContractInfo(ctx, contractAddress) - if contractInfo == nil { - return types.ErrBeforeSendHookNotWhitelisted.Wrapf("contract with address (%s) does not exist", contractAddress.String()) - } - codeID := contractInfo.CodeID - whitelistedHooks := k.GetParams(ctx).WhitelistedHooks - denomCreator, _, err := types.DeconstructDenom(denom) - if err != nil { - return types.ErrBeforeSendHookNotWhitelisted.Wrapf("invalid denom: %s", denom) - } - - for _, hook := range whitelistedHooks { - if hook.CodeID == codeID && hook.DenomCreator == denomCreator { - return nil - } - } - - return types.ErrBeforeSendHookNotWhitelisted.Wrapf("no whitelist for contract with codeID (%d) and denomCreator (%s) ", codeID, denomCreator) -} From 01622b6a0d3244b1ab82e7306a4d702faedb8101 Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Thu, 20 Jun 2024 14:03:07 -0400 Subject: [PATCH 13/23] small migration fixes --- x/tokenfactory/migrations/v2/store.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/x/tokenfactory/migrations/v2/store.go b/x/tokenfactory/migrations/v2/store.go index 408317c17..3c0588837 100644 --- a/x/tokenfactory/migrations/v2/store.go +++ b/x/tokenfactory/migrations/v2/store.go @@ -6,10 +6,10 @@ import ( "cosmossdk.io/store/prefix" + errorsmod "cosmossdk.io/errors" storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/neutron-org/neutron/v4/x/tokenfactory/types" v1beta1types "github.com/neutron-org/neutron/v4/x/tokenfactory/types/v1beta1" ) @@ -84,6 +84,9 @@ func migrateHooks(ctx sdk.Context, storeKey storetypes.StoreKey, keeper TokenFac for ; iterator.Valid(); iterator.Next() { keyParts := strings.Split(string(iterator.Key()), types.KeySeparator) + if len(keyParts) != 3 { + return errors.New("cannot parse BeforeSendHook data") + } // Hooks and authorityMetadata are in the same store, we only care about the hooks if keyParts[2] == types.BeforeSendHookAddressPrefixKey { @@ -103,7 +106,7 @@ func migrateHooks(ctx sdk.Context, storeKey storetypes.StoreKey, keeper TokenFac err := iterator.Close() if err != nil { - return err + return errorsmod.Wrap(err, "iterator failed to close after migration") } ctx.Logger().Info("Finished migrating tokenfactory hooks") From 33b28465862c90fe9b8253fc910f545fa05fc3cb Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Thu, 20 Jun 2024 14:12:11 -0400 Subject: [PATCH 14/23] fix: dont write during iterations --- x/tokenfactory/migrations/v2/store.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/x/tokenfactory/migrations/v2/store.go b/x/tokenfactory/migrations/v2/store.go index 3c0588837..037dcb432 100644 --- a/x/tokenfactory/migrations/v2/store.go +++ b/x/tokenfactory/migrations/v2/store.go @@ -81,7 +81,7 @@ func migrateHooks(ctx sdk.Context, storeKey storetypes.StoreKey, keeper TokenFac // get hook store store := prefix.NewStore(ctx.KVStore(storeKey), []byte(types.DenomsPrefixKey)) iterator := storetypes.KVStorePrefixIterator(store, []byte{}) - + hooksToRemove := make([][]byte, 0) for ; iterator.Valid(); iterator.Next() { keyParts := strings.Split(string(iterator.Key()), types.KeySeparator) if len(keyParts) != 3 { @@ -98,8 +98,7 @@ func migrateHooks(ctx sdk.Context, storeKey storetypes.StoreKey, keeper TokenFac err = keeper.AssertIsHookWhitelisted(ctx, denom, contractAddr) if err != nil { - // If hook is not whitelisted delete it - store.Delete(iterator.Key()) + hooksToRemove = append(hooksToRemove, iterator.Key()) } } } @@ -109,6 +108,11 @@ func migrateHooks(ctx sdk.Context, storeKey storetypes.StoreKey, keeper TokenFac return errorsmod.Wrap(err, "iterator failed to close after migration") } + // Delete all non-whitelisted hooks + for _, k := range hooksToRemove { + store.Delete(k) + } + ctx.Logger().Info("Finished migrating tokenfactory hooks") return nil From 024ce3d6fc3cf8e57031f6ae104900ce95530efa Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Thu, 20 Jun 2024 14:17:52 -0400 Subject: [PATCH 15/23] lint --- x/tokenfactory/migrations/v2/store.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/tokenfactory/migrations/v2/store.go b/x/tokenfactory/migrations/v2/store.go index 037dcb432..9a34e5f11 100644 --- a/x/tokenfactory/migrations/v2/store.go +++ b/x/tokenfactory/migrations/v2/store.go @@ -10,6 +10,7 @@ import ( storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/neutron-org/neutron/v4/x/tokenfactory/types" v1beta1types "github.com/neutron-org/neutron/v4/x/tokenfactory/types/v1beta1" ) From 36fd28a57908934c5ae2c3d9aa1cca346c8b3afb Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Thu, 20 Jun 2024 15:10:16 -0400 Subject: [PATCH 16/23] Add error logging for skipped hooks --- x/tokenfactory/keeper/before_send.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x/tokenfactory/keeper/before_send.go b/x/tokenfactory/keeper/before_send.go index ea592478b..cf471a497 100644 --- a/x/tokenfactory/keeper/before_send.go +++ b/x/tokenfactory/keeper/before_send.go @@ -125,6 +125,12 @@ func (k Keeper) callBeforeSendListener(ctx context.Context, from, to sdk.AccAddr // It is here as an emergency override if we want to shutoff a hook. We do not return the error because once it is removed from the whitelist // a hook should not be able to block a send. if err := k.AssertIsHookWhitelisted(c, coin.Denom, cwAddr); err != nil { + c.Logger().Error( + "Skipped hook execution due to missing whitelist", + "err", err, + "denom", coin.Amount, + "contract", cwAddr.String(), + ) continue } From 2c7fb7d92ccd243075b0deb1cbbe726215f232ad Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Thu, 20 Jun 2024 19:05:26 -0400 Subject: [PATCH 17/23] Add whitelisted astroport contracts to TF migration --- x/tokenfactory/migrations/v2/store.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/x/tokenfactory/migrations/v2/store.go b/x/tokenfactory/migrations/v2/store.go index 9a34e5f11..96a69f144 100644 --- a/x/tokenfactory/migrations/v2/store.go +++ b/x/tokenfactory/migrations/v2/store.go @@ -38,6 +38,14 @@ var WhitelistedHooks = []*types.WhitelistedHook{ CodeID: 944, DenomCreator: "neutron1zlf3hutsa4qnmue53lz2tfxrutp8y2e3rj4nkghg3rupgl4mqy8s5jgxsn", }, + { // USDC <> NTRN balances tracker + CodeID: 944, + DenomCreator: "neutron18c8qejysp4hgcfuxdpj4wf29mevzwllz5yh8uayjxamwtrs0n9fshq9vtv", + }, + { // NTRN <> ATOM balances tracker + CodeID: 944, + DenomCreator: "neutron145z3nj7yqft2vpugr5a5p7jsnagvms90tvtej45g4s0xkqalhy7sj20vgz", + }, { // NFA.zoneV1 CodeID: 1265, DenomCreator: "neutron1pwjn3tsumm3j7v7clzqhjsaukv4tdjlclhdytawhet68fwlz84fqcrdyf5", From 01c1923a1dc7fc41c0cc04d08d49f3dba8bf9069 Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Thu, 20 Jun 2024 19:33:27 -0400 Subject: [PATCH 18/23] Add missing comma in init-neutrond.sh --- network/init-neutrond.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network/init-neutrond.sh b/network/init-neutrond.sh index ec671d986..563572a2b 100755 --- a/network/init-neutrond.sh +++ b/network/init-neutrond.sh @@ -721,7 +721,7 @@ echo $DAO_CONTRACT_ADDRESS_B64 set_genesis_param admins "[\"$NEUTRON_CHAIN_MANAGER_CONTRACT_ADDRESS\"]" # admin module set_genesis_param treasury_address "\"$DAO_CONTRACT_ADDRESS\"" # feeburner -set_genesis_param fee_collector_address "\"$DAO_CONTRACT_ADDRESS\"" # tokenfactory +set_genesis_param fee_collector_address "\"$DAO_CONTRACT_ADDRESS\"," # tokenfactory set_genesis_param security_address "\"$SECURITY_SUBDAO_CORE_CONTRACT_ADDRESS\"," # cron set_genesis_param limit 5 # cron #set_genesis_param allow_messages "[\"*\"]" # interchainaccounts From a097ad9d522d6813ad3dbdb55e14206dfb284ac1 Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Thu, 20 Jun 2024 21:40:18 -0400 Subject: [PATCH 19/23] better comments on TF params.proto --- docs/static/swagger.yaml | 43 +++++++++++++++++++++---- proto/osmosis/tokenfactory/params.proto | 5 ++- x/tokenfactory/types/params.pb.go | 5 ++- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/docs/static/swagger.yaml b/docs/static/swagger.yaml index a10ae098e..a533cb0fa 100644 --- a/docs/static/swagger.yaml +++ b/docs/static/swagger.yaml @@ -18684,10 +18684,18 @@ definitions: type: string denom_creator: type: string + title: >- + WhitelistedHook describes a beforeSendHook which is allowed to be + added and executed + + SetBeforeSendHook can only be called on denoms where the denom + creator and + + code_id for the `contract_addr` match a WhitelistedHook type: object title: >- - HookWhitelist is the list of hooks which are allowed to be added and - executed + whitelisted_hooks is the list of hooks which are allowed to be added + and executed type: array type: object osmosis.tokenfactory.WhitelistedHook: @@ -18697,6 +18705,13 @@ definitions: type: string denom_creator: type: string + title: >- + WhitelistedHook describes a beforeSendHook which is allowed to be added + and executed + + SetBeforeSendHook can only be called on denoms where the denom creator and + + code_id for the `contract_addr` match a WhitelistedHook type: object osmosis.tokenfactory.v1beta1.DenomAuthorityMetadata: description: |- @@ -18803,10 +18818,18 @@ definitions: type: string denom_creator: type: string + title: >- + WhitelistedHook describes a beforeSendHook which is allowed to + be added and executed + + SetBeforeSendHook can only be called on denoms where the denom + creator and + + code_id for the `contract_addr` match a WhitelistedHook type: object title: >- - HookWhitelist is the list of hooks which are allowed to be added - and executed + whitelisted_hooks is the list of hooks which are allowed to be + added and executed type: array type: object type: object @@ -43784,10 +43807,18 @@ paths: type: string denom_creator: type: string + title: >- + WhitelistedHook describes a beforeSendHook which is + allowed to be added and executed + + SetBeforeSendHook can only be called on denoms where the + denom creator and + + code_id for the `contract_addr` match a WhitelistedHook type: object title: >- - HookWhitelist is the list of hooks which are allowed to be - added and executed + whitelisted_hooks is the list of hooks which are allowed + to be added and executed type: array type: object type: object diff --git a/proto/osmosis/tokenfactory/params.proto b/proto/osmosis/tokenfactory/params.proto index ef7a36f6d..563a17a4f 100644 --- a/proto/osmosis/tokenfactory/params.proto +++ b/proto/osmosis/tokenfactory/params.proto @@ -7,6 +7,9 @@ import "gogoproto/gogo.proto"; option go_package = "github.com/neutron-org/neutron/v4/x/tokenfactory/types"; +// WhitelistedHook describes a beforeSendHook which is allowed to be added and executed +// SetBeforeSendHook can only be called on denoms where the denom creator and +// code_id for the `contract_addr` match a WhitelistedHook message WhitelistedHook { uint64 code_id = 1 [(gogoproto.customname) = "CodeID"]; string denom_creator = 2; @@ -35,6 +38,6 @@ message Params { // FeeCollectorAddress is the address where fees collected from denom creation // are sent to string fee_collector_address = 3; - // HookWhitelist is the list of hooks which are allowed to be added and executed + // whitelisted_hooks is the list of hooks which are allowed to be added and executed repeated WhitelistedHook whitelisted_hooks = 4; } diff --git a/x/tokenfactory/types/params.pb.go b/x/tokenfactory/types/params.pb.go index 6138df390..48cfdb88f 100644 --- a/x/tokenfactory/types/params.pb.go +++ b/x/tokenfactory/types/params.pb.go @@ -27,6 +27,9 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// WhitelistedHook describes a beforeSendHook which is allowed to be added and executed +// SetBeforeSendHook can only be called on denoms where the denom creator and +// code_id for the `contract_addr` match a WhitelistedHook type WhitelistedHook struct { CodeID uint64 `protobuf:"varint,1,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` DenomCreator string `protobuf:"bytes,2,opt,name=denom_creator,json=denomCreator,proto3" json:"denom_creator,omitempty"` @@ -93,7 +96,7 @@ type Params struct { // FeeCollectorAddress is the address where fees collected from denom creation // are sent to FeeCollectorAddress string `protobuf:"bytes,3,opt,name=fee_collector_address,json=feeCollectorAddress,proto3" json:"fee_collector_address,omitempty"` - // HookWhitelist is the list of hooks which are allowed to be added and executed + // whitelisted_hooks is the list of hooks which are allowed to be added and executed WhitelistedHooks []*WhitelistedHook `protobuf:"bytes,4,rep,name=whitelisted_hooks,json=whitelistedHooks,proto3" json:"whitelisted_hooks,omitempty"` } From daf306ddee9402879acad215dd2e5f2d99f49c8f Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Fri, 21 Jun 2024 10:35:56 -0400 Subject: [PATCH 20/23] make errors clearer --- x/tokenfactory/keeper/before_send.go | 2 +- x/tokenfactory/migrations/v2/store.go | 5 +++-- x/tokenfactory/types/params.go | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/x/tokenfactory/keeper/before_send.go b/x/tokenfactory/keeper/before_send.go index cf471a497..547222124 100644 --- a/x/tokenfactory/keeper/before_send.go +++ b/x/tokenfactory/keeper/before_send.go @@ -128,7 +128,7 @@ func (k Keeper) callBeforeSendListener(ctx context.Context, from, to sdk.AccAddr c.Logger().Error( "Skipped hook execution due to missing whitelist", "err", err, - "denom", coin.Amount, + "denom", coin.Denom, "contract", cwAddr.String(), ) continue diff --git a/x/tokenfactory/migrations/v2/store.go b/x/tokenfactory/migrations/v2/store.go index 96a69f144..17a71f793 100644 --- a/x/tokenfactory/migrations/v2/store.go +++ b/x/tokenfactory/migrations/v2/store.go @@ -2,6 +2,7 @@ package v2 import ( "errors" + "fmt" "strings" "cosmossdk.io/store/prefix" @@ -94,7 +95,7 @@ func migrateHooks(ctx sdk.Context, storeKey storetypes.StoreKey, keeper TokenFac for ; iterator.Valid(); iterator.Next() { keyParts := strings.Split(string(iterator.Key()), types.KeySeparator) if len(keyParts) != 3 { - return errors.New("cannot parse BeforeSendHook data") + return fmt.Errorf("cannot parse BeforeSendHook data key: %s", string(iterator.Key())) } // Hooks and authorityMetadata are in the same store, we only care about the hooks @@ -102,7 +103,7 @@ func migrateHooks(ctx sdk.Context, storeKey storetypes.StoreKey, keeper TokenFac denom := keyParts[1] contractAddr, err := sdk.AccAddressFromBech32(string(iterator.Value())) if err != nil { - return errors.New("cannot parse hook contract address") + return fmt.Errorf("cannot parse hook contract address: %s", string(iterator.Value())) } err = keeper.AssertIsHookWhitelisted(ctx, denom, contractAddr) diff --git a/x/tokenfactory/types/params.go b/x/tokenfactory/types/params.go index 8dcd4a029..10328c10e 100644 --- a/x/tokenfactory/types/params.go +++ b/x/tokenfactory/types/params.go @@ -50,15 +50,15 @@ func (p Params) Validate() error { } if err := validateDenomCreationFee(p.DenomCreationFee); err != nil { - return fmt.Errorf("failed to validate params: %w", err) + return fmt.Errorf("failed to validate DenomCreationFee: %w", err) } if err := validateFeeCollectorAddress(p.FeeCollectorAddress); err != nil { - return fmt.Errorf("failed to validate params: %w", err) + return fmt.Errorf("failed to validate FeeCollectorAddress: %w", err) } if err := validateWhitelistedHooks(p.WhitelistedHooks); err != nil { - return fmt.Errorf("failed to validate params: %w", err) + return fmt.Errorf("failed to validate WhitelistedHooks: %w", err) } return nil From 9077e4919679e2818c7ff9f45f76d6172ac461d6 Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Fri, 21 Jun 2024 11:50:12 -0400 Subject: [PATCH 21/23] fixes to tokenfactory query cli 1. Add missing GetCmdBeforeSendHook query 2. Correctly parse denoms with slashes in subdenom 3. fix typo hiik => hook --- x/tokenfactory/client/cli/query.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/x/tokenfactory/client/cli/query.go b/x/tokenfactory/client/cli/query.go index 83dbc0f30..5b62e060a 100644 --- a/x/tokenfactory/client/cli/query.go +++ b/x/tokenfactory/client/cli/query.go @@ -27,6 +27,7 @@ func GetQueryCmd() *cobra.Command { GetParams(), GetCmdDenomAuthorityMetadata(), GetCmdDenomsFromCreator(), + GetCmdBeforeSendHook(), ) return cmd @@ -124,10 +125,10 @@ func GetCmdDenomsFromCreator() *cobra.Command { return cmd } -// GetCmdDenomAuthorityMetadata returns the authority metadata for a queried denom +// GetCmdBeforeSendHook returns the BeforeSendHook for a queried denom func GetCmdBeforeSendHook() *cobra.Command { cmd := &cobra.Command{ - Use: "before-send-hiik [denom] [flags]", + Use: "before-send-hook [denom] [flags]", Short: "Get the before send hook for a specific denom", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -137,15 +138,15 @@ func GetCmdBeforeSendHook() *cobra.Command { } queryClient := types.NewQueryClient(clientCtx) - denom := strings.Split(args[0], "/") - - if len(denom) != 3 { - return fmt.Errorf("invalid denom format, expected format: factory/[creator]/[subdenom]") + denom := args[0] + creator, subdenom, err := types.DeconstructDenom(denom) + if err != nil { + return err } res, err := queryClient.BeforeSendHookAddress(cmd.Context(), &types.QueryBeforeSendHookAddressRequest{ - Creator: denom[1], - Subdenom: denom[2], + Creator: creator, + Subdenom: subdenom, }) if err != nil { return err From 32bf31b283e1cfd3a9c9d6eaedd9913838754982 Mon Sep 17 00:00:00 2001 From: Julian Compagni Portis Date: Fri, 21 Jun 2024 11:55:22 -0400 Subject: [PATCH 22/23] update code_ids for astroport contract whitelisting --- x/tokenfactory/migrations/v2/store.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/tokenfactory/migrations/v2/store.go b/x/tokenfactory/migrations/v2/store.go index 17a71f793..e36561925 100644 --- a/x/tokenfactory/migrations/v2/store.go +++ b/x/tokenfactory/migrations/v2/store.go @@ -40,11 +40,11 @@ var WhitelistedHooks = []*types.WhitelistedHook{ DenomCreator: "neutron1zlf3hutsa4qnmue53lz2tfxrutp8y2e3rj4nkghg3rupgl4mqy8s5jgxsn", }, { // USDC <> NTRN balances tracker - CodeID: 944, + CodeID: 1473, DenomCreator: "neutron18c8qejysp4hgcfuxdpj4wf29mevzwllz5yh8uayjxamwtrs0n9fshq9vtv", }, { // NTRN <> ATOM balances tracker - CodeID: 944, + CodeID: 1473, DenomCreator: "neutron145z3nj7yqft2vpugr5a5p7jsnagvms90tvtej45g4s0xkqalhy7sj20vgz", }, { // NFA.zoneV1 From 3e26ebbb8f3aed251af2828aca9d29666feb8622 Mon Sep 17 00:00:00 2001 From: pr0n00gler Date: Fri, 21 Jun 2024 19:44:00 +0300 Subject: [PATCH 23/23] do not use a separate event manager for sudo calls in tokenfactory --- x/tokenfactory/keeper/before_send.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/x/tokenfactory/keeper/before_send.go b/x/tokenfactory/keeper/before_send.go index 547222124..40e81ba8b 100644 --- a/x/tokenfactory/keeper/before_send.go +++ b/x/tokenfactory/keeper/before_send.go @@ -162,17 +162,16 @@ func (k Keeper) callBeforeSendListener(ctx context.Context, from, to sdk.AccAddr if err != nil { return err } - em := sdk.NewEventManager() // if its track before send, apply gas meter to prevent infinite loop if blockBeforeSend { - _, err = k.contractKeeper.Sudo(c.WithEventManager(em), cwAddr, msgBz) + _, err = k.contractKeeper.Sudo(c, cwAddr, msgBz) if err != nil { return errorsmod.Wrapf(err, "failed to call before send hook for denom %s", coin.Denom) } } else { childCtx := c.WithGasMeter(types2.NewGasMeter(types.TrackBeforeSendGasLimit)) - _, err = k.contractKeeper.Sudo(childCtx.WithEventManager(em), cwAddr, msgBz) + _, err = k.contractKeeper.Sudo(childCtx, cwAddr, msgBz) if err != nil { return errorsmod.Wrapf(err, "failed to call before send hook for denom %s", coin.Denom) }