diff --git a/.github/workflows/integration-test-matrix.json b/.github/workflows/integration-test-matrix.json index 1c29fdc645..507cf1bc0d 100644 --- a/.github/workflows/integration-test-matrix.json +++ b/.github/workflows/integration-test-matrix.json @@ -64,11 +64,10 @@ ] }, { - "_comment": "Suites: SeiDB State Store, Mint & Staking & Bank, Distribution. SeiDB State Store runs first because it asserts absolute wasm code counts (genesis + its own fixtures). TestMintModule asserts an absolute usei total supply, so nothing upstream of it in this row may mint or burn usei (SeiDB SS is safe today: fees are not burned and tokenfactory creation does not burn usei).", + "_comment": "Suites: SeiDB State Store, Mint & Staking & Bank, Distribution. SeiDB State Store runs first because it asserts absolute wasm code counts (genesis + its own fixtures). TestMintModule asserts an absolute usei total supply, so nothing upstream of it in this row may mint or burn usei (SeiDB SS is safe today: fees are not burned).", "name": "Cosmos Modules (SeiDB SS, Mint & Staking & Bank, Distribution)", "scripts": [ "docker exec sei-node-0 integration_test/contracts/deploy_wasm_contracts.sh", - "docker exec sei-node-0 integration_test/contracts/create_tokenfactory_denoms.sh", "go test -tags yaml_integration -v -timeout $JOB_TIMEOUT ./integration_test/runner/... -run TestSeiDBStateStore", "go test -tags yaml_integration -v -timeout $JOB_TIMEOUT ./integration_test/runner/... -run \"TestMintModule|TestStakingModule|TestBankModule\"", "go test -tags yaml_integration -v -timeout $JOB_TIMEOUT ./integration_test/runner/... -run TestDistributionModule" diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fa344d463..e93e58046e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## Unreleased sei-chain +* [#4536](https://github.com/sei-protocol/sei-chain/pull/4536) Remove the tokenfactory module behind the v6.8 upgrade: module, store, params, protobuf schema, CLI, wasm bindings, the bank `factory/` denom transfer allowlist and tooling are gone; only the tokenfactory Msg types remain decodable so historical blocks still trace. Existing `factory/` balances stay in bank but can no longer be minted or burned, and denoms that had a transfer allowlist become freely transferable. The upgrade deletes at most 1,000 allowlists from the bank store and leaves any beyond that in place, unenforced. App-hash breaking at the upgrade height. * [#4319](https://github.com/sei-protocol/sei-chain/pull/4319) Remove the oracle module behind the v6.8 upgrade: module, store, protobuf schema, wasm query route and tooling are gone; only the oracle Msg types remain decodable so historical blocks still trace. App-hash breaking at the upgrade height. * [#4332](https://github.com/sei-protocol/sei-chain/pull/4332) Bump sei-protocol/go-ethereum to v1.15.7-sei-21 * [#4329](https://github.com/sei-protocol/sei-chain/pull/4329) Add Giga fetch/serve and BlockDB prune metrics diff --git a/app/app.go b/app/app.go index 23941da89d..e88e5c812d 100644 --- a/app/app.go +++ b/app/app.go @@ -100,6 +100,7 @@ import ( "github.com/sei-protocol/sei-chain/app/migration" appparams "github.com/sei-protocol/sei-chain/app/params" "github.com/sei-protocol/sei-chain/app/retiredoracle" + "github.com/sei-protocol/sei-chain/app/retiredtokenfactory" "github.com/sei-protocol/sei-chain/app/upgrades" "github.com/sei-protocol/sei-chain/app/upgrades/kvrepair" v0upgrade "github.com/sei-protocol/sei-chain/app/upgrades/v0" @@ -139,9 +140,6 @@ import ( mintclient "github.com/sei-protocol/sei-chain/x/mint/client/cli" mintkeeper "github.com/sei-protocol/sei-chain/x/mint/keeper" minttypes "github.com/sei-protocol/sei-chain/x/mint/types" - tokenfactorymodule "github.com/sei-protocol/sei-chain/x/tokenfactory" - tokenfactorykeeper "github.com/sei-protocol/sei-chain/x/tokenfactory/keeper" - tokenfactorytypes "github.com/sei-protocol/sei-chain/x/tokenfactory/types" dbm "github.com/tendermint/tm-db" "go.opentelemetry.io/otel/attribute" otelmetric "go.opentelemetry.io/otel/metric" @@ -206,7 +204,6 @@ var ( evm.AppModuleBasic{}, wasm.AppModuleBasic{}, epochmodule.AppModuleBasic{}, - tokenfactorymodule.AppModuleBasic{}, // this line is used by starport scaffolding # stargate/app/moduleBasic ) @@ -220,7 +217,6 @@ var ( govtypes.ModuleName: {authtypes.Burner}, wasm.ModuleName: {authtypes.Burner}, evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, - tokenfactorytypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // this line is used by starport scaffolding # stargate/app/maccPerms } @@ -229,7 +225,7 @@ var ( // retiredModuleAccounts are module accounts whose modules no longer exist // but whose deterministic addresses stay blocked so funds cannot be sent // to an account nothing can sign for. - retiredModuleAccounts = []string{"transfer"} + retiredModuleAccounts = []string{"transfer", retiredtokenfactory.ModuleName} // kvStoreKeyNames is the canonical, in-order list of module KV store // names mounted on the SeiDB / memiavl backend. It is the single source @@ -244,7 +240,6 @@ var ( evidencetypes.StoreKey, evmtypes.StoreKey, wasm.StoreKey, epochmoduletypes.StoreKey, - tokenfactorytypes.StoreKey, // this line is used by starport scaffolding # stargate/app/storeKey } @@ -381,8 +376,6 @@ type App struct { EpochKeeper epochmodulekeeper.Keeper - TokenFactoryKeeper tokenfactorykeeper.Keeper - BeginBlockKeepers legacyabci.BeginBlockKeepers EndBlockKeepers legacyabci.EndBlockKeepers CheckTxKeepers legacyabci.CheckTxKeepers @@ -583,22 +576,12 @@ func New( ).SetHooks(epochmoduletypes.NewMultiEpochHooks( app.MintKeeper.Hooks())) - app.TokenFactoryKeeper = tokenfactorykeeper.NewKeeper( - appCodec, - app.keys[tokenfactorytypes.StoreKey], - app.GetSubspace(tokenfactorytypes.ModuleName), - app.AccountKeeper, - app.BankKeeper.(bankkeeper.BaseKeeper).WithMintCoinsRestriction(tokenfactorytypes.NewTokenFactoryDenomMintCoinsRestriction()), - app.DistrKeeper, - ) - // The last arguments can contain custom message handlers, and custom query handlers, // if we want to allow any custom callbacks supportedFeatures := "iterator,staking,stargate,sei" wasmOpts = append( wasmbinding.RegisterCustomPlugins( &app.EpochKeeper, - &app.TokenFactoryKeeper, &app.AccountKeeper, app.MsgServiceRouter(), app.BankKeeper, @@ -812,7 +795,6 @@ func New( wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper), evm.NewAppModule(appCodec, &app.EvmKeeper), epochModule, - tokenfactorymodule.NewAppModule(app.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), // this line is used by starport scaffolding # stargate/app/appModule ) @@ -862,7 +844,6 @@ func New( genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, - tokenfactorytypes.ModuleName, epochmoduletypes.ModuleName, wasm.ModuleName, evmtypes.ModuleName, @@ -1047,7 +1028,7 @@ func (app *App) SetStoreUpgradeHandlers() { if upgradeInfo.Name == "1.1.1beta" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { storeUpgrades := storetypes.StoreUpgrades{ - Added: []string{tokenfactorytypes.StoreKey}, + Added: []string{retiredtokenfactory.ModuleName}, } // configure store loader that checks if version == upgradeHeight and applies store upgrades @@ -2701,7 +2682,6 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(wasm.ModuleName) paramsKeeper.Subspace(evmtypes.ModuleName) paramsKeeper.Subspace(epochmoduletypes.ModuleName) - paramsKeeper.Subspace(tokenfactorytypes.ModuleName) paramsKeeper.Subspace(migration.SubspaceName).WithKeyTable(migration.ParamKeyTable()) // this line is used by starport scaffolding # stargate/app/paramSubspace diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 73fa4191a3..a69826a13c 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -110,11 +110,6 @@ func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sd return valAddr } -// SetupTokenFactory sets up a token module account for the TokenFactoryKeeper. -func (s *KeeperTestHelper) SetupTokenFactory() { - s.App.TokenFactoryKeeper.CreateModuleAccount(s.Ctx) -} - // EndBlock ends the block. func (s *KeeperTestHelper) EndBlock() { legacyabci.EndBlock(s.Ctx, s.Ctx.BlockHeight(), 0, s.App.EndBlockKeepers) diff --git a/app/encoding.go b/app/encoding.go index 651ec61a44..3141615c06 100644 --- a/app/encoding.go +++ b/app/encoding.go @@ -3,6 +3,7 @@ package app import ( "github.com/sei-protocol/sei-chain/app/params" "github.com/sei-protocol/sei-chain/app/retiredoracle" + "github.com/sei-protocol/sei-chain/app/retiredtokenfactory" "github.com/sei-protocol/sei-chain/app/retiredvesting" "github.com/sei-protocol/sei-chain/sei-cosmos/std" ) @@ -16,6 +17,8 @@ func MakeEncodingConfig() params.EncodingConfig { ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) retiredoracle.RegisterInterfaces(encodingConfig.InterfaceRegistry) retiredoracle.RegisterLegacyAminoCodec(encodingConfig.Amino) + retiredtokenfactory.RegisterInterfaces(encodingConfig.InterfaceRegistry) + retiredtokenfactory.RegisterLegacyAminoCodec(encodingConfig.Amino) retiredvesting.RegisterInterfaces(encodingConfig.InterfaceRegistry) return encodingConfig } @@ -29,6 +32,8 @@ func MakeLegacyEncodingConfig() params.EncodingConfig { ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) retiredoracle.RegisterInterfaces(encodingConfig.InterfaceRegistry) retiredoracle.RegisterLegacyAminoCodec(encodingConfig.Amino) + retiredtokenfactory.RegisterInterfaces(encodingConfig.InterfaceRegistry) + retiredtokenfactory.RegisterLegacyAminoCodec(encodingConfig.Amino) retiredvesting.RegisterInterfaces(encodingConfig.InterfaceRegistry) return encodingConfig } diff --git a/x/tokenfactory/types/codec.go b/app/retiredtokenfactory/codec.go similarity index 57% rename from x/tokenfactory/types/codec.go rename to app/retiredtokenfactory/codec.go index 6867529d80..c7c7b0cfb3 100644 --- a/x/tokenfactory/types/codec.go +++ b/app/retiredtokenfactory/codec.go @@ -1,44 +1,29 @@ -package types +package retiredtokenfactory import ( "github.com/sei-protocol/sei-chain/sei-cosmos/codec" - cdctypes "github.com/sei-protocol/sei-chain/sei-cosmos/codec/types" + codectypes "github.com/sei-protocol/sei-chain/sei-cosmos/codec/types" sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - - // this line is used by starport scaffolding # 1 - "github.com/sei-protocol/sei-chain/sei-cosmos/types/msgservice" ) -func RegisterCodec(cdc *codec.LegacyAmino) { - cdc.RegisterConcrete(&MsgCreateDenom{}, "tokenfactory/MsgCreateDenom", nil) - cdc.RegisterConcrete(&MsgUpdateDenom{}, "tokenfactory/MsgUpdateDenom", nil) - cdc.RegisterConcrete(&MsgMint{}, "tokenfactory/MsgMint", nil) - cdc.RegisterConcrete(&MsgBurn{}, "tokenfactory/MsgBurn", nil) - cdc.RegisterConcrete(&MsgChangeAdmin{}, "tokenfactory/MsgChangeAdmin", nil) - cdc.RegisterConcrete(&MsgSetDenomMetadata{}, "tokenfactory/MsgSetDenomMetadata", nil) -} - -func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { registry.RegisterImplementations((*sdk.Msg)(nil), &MsgCreateDenom{}, - ) - registry.RegisterImplementations((*sdk.Msg)(nil), &MsgUpdateDenom{}, - ) - registry.RegisterImplementations((*sdk.Msg)(nil), &MsgMint{}, - ) - registry.RegisterImplementations((*sdk.Msg)(nil), &MsgBurn{}, - ) - registry.RegisterImplementations((*sdk.Msg)(nil), &MsgChangeAdmin{}, - ) - registry.RegisterImplementations((*sdk.Msg)(nil), &MsgSetDenomMetadata{}, ) +} - msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgCreateDenom{}, "tokenfactory/MsgCreateDenom", nil) + cdc.RegisterConcrete(&MsgUpdateDenom{}, "tokenfactory/MsgUpdateDenom", nil) + cdc.RegisterConcrete(&MsgMint{}, "tokenfactory/MsgMint", nil) + cdc.RegisterConcrete(&MsgBurn{}, "tokenfactory/MsgBurn", nil) + cdc.RegisterConcrete(&MsgChangeAdmin{}, "tokenfactory/MsgChangeAdmin", nil) + cdc.RegisterConcrete(&MsgSetDenomMetadata{}, "tokenfactory/MsgSetDenomMetadata", nil) } var ( @@ -47,8 +32,7 @@ var ( ) func init() { - RegisterCodec(amino) + RegisterLegacyAminoCodec(amino) sdk.RegisterLegacyAminoCodec(amino) - amino.Seal() } diff --git a/app/retiredtokenfactory/errors.go b/app/retiredtokenfactory/errors.go new file mode 100644 index 0000000000..b952c86153 --- /dev/null +++ b/app/retiredtokenfactory/errors.go @@ -0,0 +1,6 @@ +package retiredtokenfactory + +import "github.com/sei-protocol/sei-chain/sei-cosmos/types/errors" + +// ErrDeprecated is the error every retired tokenfactory message fails validation with. +var ErrDeprecated = errors.Register(ModuleName, 26, "tokenfactory module is deprecated") // codes 2-25 keep their historical meanings diff --git a/app/retiredtokenfactory/msgs.go b/app/retiredtokenfactory/msgs.go new file mode 100644 index 0000000000..55cf14fdef --- /dev/null +++ b/app/retiredtokenfactory/msgs.go @@ -0,0 +1,107 @@ +// Package retiredtokenfactory provides decode-only compatibility for retired tokenfactory transactions. +package retiredtokenfactory + +import ( + sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" +) + +const ( + // ModuleName is the name of the retired tokenfactory module, which also names + // its deleted store and its error codespace. + ModuleName = "tokenfactory" + + TypeMsgCreateDenom = "create_denom" + TypeMsgUpdateDenom = "update_denom" + TypeMsgMint = "mint" + TypeMsgBurn = "burn" + TypeMsgChangeAdmin = "change_admin" + TypeMsgSetDenomMetadata = "set_denom_metadata" +) + +var ( + _ sdk.Msg = (*MsgCreateDenom)(nil) + _ sdk.Msg = (*MsgUpdateDenom)(nil) + _ sdk.Msg = (*MsgMint)(nil) + _ sdk.Msg = (*MsgBurn)(nil) + _ sdk.Msg = (*MsgChangeAdmin)(nil) + _ sdk.Msg = (*MsgSetDenomMetadata)(nil) +) + +func (m MsgCreateDenom) Route() string { return ModuleName } + +func (m MsgCreateDenom) Type() string { return TypeMsgCreateDenom } + +func (m MsgCreateDenom) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgCreateDenom) GetSigners() []sdk.AccAddress { return senderSigners(m.Sender) } + +func (m MsgCreateDenom) ValidateBasic() error { return ErrDeprecated } + +func (m MsgUpdateDenom) Route() string { return ModuleName } + +func (m MsgUpdateDenom) Type() string { return TypeMsgUpdateDenom } + +func (m MsgUpdateDenom) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgUpdateDenom) GetSigners() []sdk.AccAddress { return senderSigners(m.Sender) } + +func (m MsgUpdateDenom) ValidateBasic() error { return ErrDeprecated } + +func (m MsgMint) Route() string { return ModuleName } + +func (m MsgMint) Type() string { return TypeMsgMint } + +func (m MsgMint) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgMint) GetSigners() []sdk.AccAddress { return senderSigners(m.Sender) } + +func (m MsgMint) ValidateBasic() error { return ErrDeprecated } + +func (m MsgBurn) Route() string { return ModuleName } + +func (m MsgBurn) Type() string { return TypeMsgBurn } + +func (m MsgBurn) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgBurn) GetSigners() []sdk.AccAddress { return senderSigners(m.Sender) } + +func (m MsgBurn) ValidateBasic() error { return ErrDeprecated } + +func (m MsgChangeAdmin) Route() string { return ModuleName } + +func (m MsgChangeAdmin) Type() string { return TypeMsgChangeAdmin } + +func (m MsgChangeAdmin) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgChangeAdmin) GetSigners() []sdk.AccAddress { return senderSigners(m.Sender) } + +func (m MsgChangeAdmin) ValidateBasic() error { return ErrDeprecated } + +func (m MsgSetDenomMetadata) Route() string { return ModuleName } + +func (m MsgSetDenomMetadata) Type() string { return TypeMsgSetDenomMetadata } + +func (m MsgSetDenomMetadata) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgSetDenomMetadata) GetSigners() []sdk.AccAddress { return senderSigners(m.Sender) } + +func (m MsgSetDenomMetadata) ValidateBasic() error { return ErrDeprecated } + +// senderSigners returns the sender as the only signer, or an empty address when +// the sender does not parse. +func senderSigners(sender string) []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(sender) + return []sdk.AccAddress{addr} +} diff --git a/app/retiredtokenfactory/retiredtokenfactory_test.go b/app/retiredtokenfactory/retiredtokenfactory_test.go new file mode 100644 index 0000000000..cd5e2c9a91 --- /dev/null +++ b/app/retiredtokenfactory/retiredtokenfactory_test.go @@ -0,0 +1,202 @@ +package retiredtokenfactory_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/encoding/protowire" + + seiapp "github.com/sei-protocol/sei-chain/app" + appparams "github.com/sei-protocol/sei-chain/app/params" + "github.com/sei-protocol/sei-chain/app/retiredtokenfactory" + codectypes "github.com/sei-protocol/sei-chain/sei-cosmos/codec/types" + sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" + sdkerrors "github.com/sei-protocol/sei-chain/sei-cosmos/types/errors" + txtypes "github.com/sei-protocol/sei-chain/sei-cosmos/types/tx" + banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" +) + +var appEncodings = []struct { + name string + config func() appparams.EncodingConfig +}{ + {"app", seiapp.MakeEncodingConfig}, + {"legacy app", seiapp.MakeLegacyEncodingConfig}, +} + +var ( + sender = sdk.AccAddress("tokenfactory-sender1") + admin = sdk.AccAddress("tokenfactory-admin-1") + denom = "factory/" + sender.String() + "/subdenom" +) + +// legacyMsg is the legacy amino surface every retired tokenfactory message keeps. +type legacyMsg interface { + sdk.Msg + Route() string + Type() string + GetSignBytes() []byte + Marshal() ([]byte, error) +} + +// retiredMsg is a retired tokenfactory message with every field set, its +// encoding under tokenfactory/tx.proto written field by field rather than by +// the retired type, and the identity and sign bytes the removed module gave it. +type retiredMsg struct { + msg legacyMsg + encoded []byte + typeURL string + msgType string + signBytes string +} + +func appendString(b []byte, field protowire.Number, s string) []byte { + return protowire.AppendString(protowire.AppendTag(b, field, protowire.BytesType), s) +} + +func appendMessage(t *testing.T, b []byte, field protowire.Number, m interface{ Marshal() ([]byte, error) }) []byte { + t.Helper() + bz, err := m.Marshal() + require.NoError(t, err) + return protowire.AppendBytes(protowire.AppendTag(b, field, protowire.BytesType), bz) +} + +func retiredMsgs(t *testing.T) []retiredMsg { + t.Helper() + createAllowList := banktypes.AllowList{Addresses: []string{sender.String(), admin.String()}} + updateAllowList := banktypes.AllowList{Addresses: []string{admin.String()}} + mintAmount := sdk.NewInt64Coin(denom, 1000) + burnAmount := sdk.NewInt64Coin(denom, 400) + metadata := banktypes.Metadata{ + Description: "description", + DenomUnits: []*banktypes.DenomUnit{{Denom: denom, Aliases: []string{"alias"}}}, + Base: denom, + Display: denom, + Name: "name", + Symbol: "SYM", + } + return []retiredMsg{ + { + msg: &retiredtokenfactory.MsgCreateDenom{Sender: sender.String(), Subdenom: "subdenom", AllowList: &createAllowList}, + encoded: appendMessage(t, appendString(appendString(nil, 1, sender.String()), 2, "subdenom"), 3, &createAllowList), + typeURL: "/seiprotocol.seichain.tokenfactory.MsgCreateDenom", + msgType: "create_denom", + signBytes: `{"type":"tokenfactory/MsgCreateDenom","value":{"allow_list":{"addresses":["sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak","sei1w3hkketwveskxar0wfuj6ctyd45kutf3ja4m2v"]},"sender":"sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak","subdenom":"subdenom"}}`, + }, + { + msg: &retiredtokenfactory.MsgUpdateDenom{Sender: sender.String(), Denom: denom, AllowList: &updateAllowList}, + encoded: appendMessage(t, appendString(appendString(nil, 1, sender.String()), 2, denom), 3, &updateAllowList), + typeURL: "/seiprotocol.seichain.tokenfactory.MsgUpdateDenom", + msgType: "update_denom", + signBytes: `{"type":"tokenfactory/MsgUpdateDenom","value":{"allow_list":{"addresses":["sei1w3hkketwveskxar0wfuj6ctyd45kutf3ja4m2v"]},"denom":"factory/sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak/subdenom","sender":"sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak"}}`, + }, + { + msg: &retiredtokenfactory.MsgMint{Sender: sender.String(), Amount: mintAmount}, + encoded: appendMessage(t, appendString(nil, 1, sender.String()), 2, &mintAmount), + typeURL: "/seiprotocol.seichain.tokenfactory.MsgMint", + msgType: "mint", + signBytes: `{"type":"tokenfactory/MsgMint","value":{"amount":{"amount":"1000","denom":"factory/sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak/subdenom"},"sender":"sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak"}}`, + }, + { + msg: &retiredtokenfactory.MsgBurn{Sender: sender.String(), Amount: burnAmount}, + encoded: appendMessage(t, appendString(nil, 1, sender.String()), 2, &burnAmount), + typeURL: "/seiprotocol.seichain.tokenfactory.MsgBurn", + msgType: "burn", + signBytes: `{"type":"tokenfactory/MsgBurn","value":{"amount":{"amount":"400","denom":"factory/sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak/subdenom"},"sender":"sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak"}}`, + }, + { + msg: &retiredtokenfactory.MsgChangeAdmin{Sender: sender.String(), Denom: denom, NewAdmin: admin.String()}, + encoded: appendString(appendString(appendString(nil, 1, sender.String()), 2, denom), 3, admin.String()), + typeURL: "/seiprotocol.seichain.tokenfactory.MsgChangeAdmin", + msgType: "change_admin", + signBytes: `{"type":"tokenfactory/MsgChangeAdmin","value":{"denom":"factory/sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak/subdenom","new_admin":"sei1w3hkketwveskxar0wfuj6ctyd45kutf3ja4m2v","sender":"sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak"}}`, + }, + { + msg: &retiredtokenfactory.MsgSetDenomMetadata{Sender: sender.String(), Metadata: metadata}, + encoded: appendMessage(t, appendString(nil, 1, sender.String()), 2, &metadata), + typeURL: "/seiprotocol.seichain.tokenfactory.MsgSetDenomMetadata", + msgType: "set_denom_metadata", + signBytes: `{"type":"tokenfactory/MsgSetDenomMetadata","value":{"metadata":{"base":"factory/sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak/subdenom","denom_units":[{"aliases":["alias"],"denom":"factory/sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak/subdenom"}],"description":"description","display":"factory/sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak/subdenom","name":"name","symbol":"SYM"},"sender":"sei1w3hkketwveskxar0wfuj6um9dejx2u33s6j3ak"}}`, + }, + } +} + +// txCarrying encodes a transaction whose only message is encoded under +// typeURL, with a placeholder signature. +func txCarrying(t *testing.T, typeURL string, encoded []byte) []byte { + t.Helper() + body, err := (&txtypes.TxBody{ + Messages: []*codectypes.Any{{TypeUrl: typeURL, Value: encoded}}, + }).Marshal() + require.NoError(t, err) + authInfo, err := (&txtypes.AuthInfo{ + Fee: &txtypes.Fee{Amount: sdk.NewCoins(sdk.NewInt64Coin("usei", 200_000)), GasLimit: 1_000_000}, + }).Marshal() + require.NoError(t, err) + txBytes, err := (&txtypes.TxRaw{ + BodyBytes: body, + AuthInfoBytes: authInfo, + Signatures: [][]byte{make([]byte, 64)}, + }).Marshal() + require.NoError(t, err) + return txBytes +} + +// TestRetiredMsgsDecode decodes a transaction carrying each retired message +// with every field set through both app transaction configs, and requires the +// retired type to carry every field and encode it back byte for byte. +func TestRetiredMsgsDecode(t *testing.T) { + for _, retired := range retiredMsgs(t) { + txBytes := txCarrying(t, retired.typeURL, retired.encoded) + for _, encoding := range appEncodings { + t.Run(retired.msgType+"/"+encoding.name, func(t *testing.T) { + tx, err := encoding.config().TxConfig.TxDecoder()(txBytes) + require.NoError(t, err) + require.Len(t, tx.GetMsgs(), 1) + got, ok := tx.GetMsgs()[0].(legacyMsg) + require.True(t, ok, "decoded %T", tx.GetMsgs()[0]) + require.Equal(t, retired.msg, got) + reencoded, err := got.Marshal() + require.NoError(t, err) + require.Equal(t, retired.encoded, reencoded) + }) + } + } +} + +// TestRetiredMsgsKeepTheirLegacyIdentity requires each retired message to keep +// the route, type and amino sign bytes the removed module gave it, so signatures +// over historical transactions still verify. +func TestRetiredMsgsKeepTheirLegacyIdentity(t *testing.T) { + for _, retired := range retiredMsgs(t) { + t.Run(retired.msgType, func(t *testing.T) { + require.Equal(t, retiredtokenfactory.ModuleName, retired.msg.Route()) + require.Equal(t, retired.msgType, retired.msg.Type()) + require.Equal(t, retired.signBytes, string(retired.msg.GetSignBytes())) + }) + } +} + +// TestRetiredMsgsAreRefused requires each retired message to keep its type URL +// and signer, and to fail validation in codespace tokenfactory with code 26. +func TestRetiredMsgsAreRefused(t *testing.T) { + for _, retired := range retiredMsgs(t) { + t.Run(retired.msgType, func(t *testing.T) { + require.Equal(t, retired.typeURL, sdk.MsgTypeURL(retired.msg)) + require.Equal(t, []sdk.AccAddress{sender}, retired.msg.GetSigners()) + + err := retired.msg.ValidateBasic() + require.ErrorIs(t, err, retiredtokenfactory.ErrDeprecated) + codespace, code, _ := sdkerrors.ABCIInfo(err, false) + require.Equal(t, "tokenfactory", codespace) + require.EqualValues(t, 26, code) + }) + } +} + +// TestRetiredTokenfactoryDoesNotRestoreModule requires the tokenfactory module +// to stay unregistered. +func TestRetiredTokenfactoryDoesNotRestoreModule(t *testing.T) { + _, registered := seiapp.ModuleBasics[retiredtokenfactory.ModuleName] + require.False(t, registered) +} diff --git a/x/tokenfactory/types/tx.pb.go b/app/retiredtokenfactory/tx.pb.go similarity index 86% rename from x/tokenfactory/types/tx.pb.go rename to app/retiredtokenfactory/tx.pb.go index 1de8004490..f5b647b881 100644 --- a/x/tokenfactory/types/tx.pb.go +++ b/app/retiredtokenfactory/tx.pb.go @@ -1,22 +1,18 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: tokenfactory/tx.proto -package types +package retiredtokenfactory import ( - context "context" fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" types1 "github.com/sei-protocol/sei-chain/sei-cosmos/types" types "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - io "io" - math "math" - math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. @@ -680,266 +676,6 @@ var fileDescriptor_51ab120c97d57038 = []byte{ 0xef, 0xe1, 0xe0, 0x56, 0x08, 0x00, 0x00, } -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// MsgClient is the client API for Msg service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type MsgClient interface { - CreateDenom(ctx context.Context, in *MsgCreateDenom, opts ...grpc.CallOption) (*MsgCreateDenomResponse, error) - UpdateDenom(ctx context.Context, in *MsgUpdateDenom, opts ...grpc.CallOption) (*MsgUpdateDenomResponse, error) - Mint(ctx context.Context, in *MsgMint, opts ...grpc.CallOption) (*MsgMintResponse, error) - Burn(ctx context.Context, in *MsgBurn, opts ...grpc.CallOption) (*MsgBurnResponse, error) - ChangeAdmin(ctx context.Context, in *MsgChangeAdmin, opts ...grpc.CallOption) (*MsgChangeAdminResponse, error) - SetDenomMetadata(ctx context.Context, in *MsgSetDenomMetadata, opts ...grpc.CallOption) (*MsgSetDenomMetadataResponse, error) -} - -type msgClient struct { - cc grpc1.ClientConn -} - -func NewMsgClient(cc grpc1.ClientConn) MsgClient { - return &msgClient{cc} -} - -func (c *msgClient) CreateDenom(ctx context.Context, in *MsgCreateDenom, opts ...grpc.CallOption) (*MsgCreateDenomResponse, error) { - out := new(MsgCreateDenomResponse) - err := c.cc.Invoke(ctx, "/seiprotocol.seichain.tokenfactory.Msg/CreateDenom", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *msgClient) UpdateDenom(ctx context.Context, in *MsgUpdateDenom, opts ...grpc.CallOption) (*MsgUpdateDenomResponse, error) { - out := new(MsgUpdateDenomResponse) - err := c.cc.Invoke(ctx, "/seiprotocol.seichain.tokenfactory.Msg/UpdateDenom", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *msgClient) Mint(ctx context.Context, in *MsgMint, opts ...grpc.CallOption) (*MsgMintResponse, error) { - out := new(MsgMintResponse) - err := c.cc.Invoke(ctx, "/seiprotocol.seichain.tokenfactory.Msg/Mint", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *msgClient) Burn(ctx context.Context, in *MsgBurn, opts ...grpc.CallOption) (*MsgBurnResponse, error) { - out := new(MsgBurnResponse) - err := c.cc.Invoke(ctx, "/seiprotocol.seichain.tokenfactory.Msg/Burn", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *msgClient) ChangeAdmin(ctx context.Context, in *MsgChangeAdmin, opts ...grpc.CallOption) (*MsgChangeAdminResponse, error) { - out := new(MsgChangeAdminResponse) - err := c.cc.Invoke(ctx, "/seiprotocol.seichain.tokenfactory.Msg/ChangeAdmin", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *msgClient) SetDenomMetadata(ctx context.Context, in *MsgSetDenomMetadata, opts ...grpc.CallOption) (*MsgSetDenomMetadataResponse, error) { - out := new(MsgSetDenomMetadataResponse) - err := c.cc.Invoke(ctx, "/seiprotocol.seichain.tokenfactory.Msg/SetDenomMetadata", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// MsgServer is the server API for Msg service. -type MsgServer interface { - CreateDenom(context.Context, *MsgCreateDenom) (*MsgCreateDenomResponse, error) - UpdateDenom(context.Context, *MsgUpdateDenom) (*MsgUpdateDenomResponse, error) - Mint(context.Context, *MsgMint) (*MsgMintResponse, error) - Burn(context.Context, *MsgBurn) (*MsgBurnResponse, error) - ChangeAdmin(context.Context, *MsgChangeAdmin) (*MsgChangeAdminResponse, error) - SetDenomMetadata(context.Context, *MsgSetDenomMetadata) (*MsgSetDenomMetadataResponse, error) -} - -// UnimplementedMsgServer can be embedded to have forward compatible implementations. -type UnimplementedMsgServer struct { -} - -func (*UnimplementedMsgServer) CreateDenom(ctx context.Context, req *MsgCreateDenom) (*MsgCreateDenomResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method CreateDenom not implemented") -} -func (*UnimplementedMsgServer) UpdateDenom(ctx context.Context, req *MsgUpdateDenom) (*MsgUpdateDenomResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UpdateDenom not implemented") -} -func (*UnimplementedMsgServer) Mint(ctx context.Context, req *MsgMint) (*MsgMintResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Mint not implemented") -} -func (*UnimplementedMsgServer) Burn(ctx context.Context, req *MsgBurn) (*MsgBurnResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Burn not implemented") -} -func (*UnimplementedMsgServer) ChangeAdmin(ctx context.Context, req *MsgChangeAdmin) (*MsgChangeAdminResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ChangeAdmin not implemented") -} -func (*UnimplementedMsgServer) SetDenomMetadata(ctx context.Context, req *MsgSetDenomMetadata) (*MsgSetDenomMetadataResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method SetDenomMetadata not implemented") -} - -func RegisterMsgServer(s grpc1.Server, srv MsgServer) { - s.RegisterService(&_Msg_serviceDesc, srv) -} - -func _Msg_CreateDenom_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgCreateDenom) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).CreateDenom(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/seiprotocol.seichain.tokenfactory.Msg/CreateDenom", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).CreateDenom(ctx, req.(*MsgCreateDenom)) - } - return interceptor(ctx, in, info, handler) -} - -func _Msg_UpdateDenom_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgUpdateDenom) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).UpdateDenom(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/seiprotocol.seichain.tokenfactory.Msg/UpdateDenom", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).UpdateDenom(ctx, req.(*MsgUpdateDenom)) - } - return interceptor(ctx, in, info, handler) -} - -func _Msg_Mint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgMint) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).Mint(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/seiprotocol.seichain.tokenfactory.Msg/Mint", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).Mint(ctx, req.(*MsgMint)) - } - return interceptor(ctx, in, info, handler) -} - -func _Msg_Burn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgBurn) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).Burn(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/seiprotocol.seichain.tokenfactory.Msg/Burn", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).Burn(ctx, req.(*MsgBurn)) - } - return interceptor(ctx, in, info, handler) -} - -func _Msg_ChangeAdmin_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgChangeAdmin) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).ChangeAdmin(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/seiprotocol.seichain.tokenfactory.Msg/ChangeAdmin", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).ChangeAdmin(ctx, req.(*MsgChangeAdmin)) - } - return interceptor(ctx, in, info, handler) -} - -func _Msg_SetDenomMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgSetDenomMetadata) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).SetDenomMetadata(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/seiprotocol.seichain.tokenfactory.Msg/SetDenomMetadata", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).SetDenomMetadata(ctx, req.(*MsgSetDenomMetadata)) - } - return interceptor(ctx, in, info, handler) -} - -var _Msg_serviceDesc = grpc.ServiceDesc{ - ServiceName: "seiprotocol.seichain.tokenfactory.Msg", - HandlerType: (*MsgServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "CreateDenom", - Handler: _Msg_CreateDenom_Handler, - }, - { - MethodName: "UpdateDenom", - Handler: _Msg_UpdateDenom_Handler, - }, - { - MethodName: "Mint", - Handler: _Msg_Mint_Handler, - }, - { - MethodName: "Burn", - Handler: _Msg_Burn_Handler, - }, - { - MethodName: "ChangeAdmin", - Handler: _Msg_ChangeAdmin_Handler, - }, - { - MethodName: "SetDenomMetadata", - Handler: _Msg_SetDenomMetadata_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "tokenfactory/tx.proto", -} - func (m *MsgCreateDenom) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) diff --git a/app/testdata/upgrade_v68_offline_source_test.go b/app/testdata/upgrade_v68_offline_source_test.go index 7979b55b9f..1a37886a41 100644 --- a/app/testdata/upgrade_v68_offline_source_test.go +++ b/app/testdata/upgrade_v68_offline_source_test.go @@ -20,6 +20,7 @@ import ( sdkerrors "github.com/sei-protocol/sei-chain/sei-cosmos/types/errors" authtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/auth/types" vestingtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/auth/vesting/types" + banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" govtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/gov/types" upgradetypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/upgrade/types" abci "github.com/sei-protocol/sei-chain/sei-tendermint/abci/types" @@ -43,17 +44,18 @@ const ( v68OfflineProposalDescription = "Substitute the expired client with 07-tendermint-1" ) -var v68OfflineSourceStores = []string{authtypes.StoreKey, "bank", "gov", "upgrade"} +var v68OfflineSourceStores = []string{authtypes.StoreKey, "bank", "gov", "params", "upgrade"} // v68OfflineDeletedStores are the stores v6.8 deletes; the source phase writes // a key into each so the target phase can prove the trees are gone. -var v68OfflineDeletedStores = []string{"capability", "ibc", "oracle", "transfer"} +var v68OfflineDeletedStores = []string{"capability", "ibc", "oracle", "tokenfactory", "transfer"} func TestV68OfflineUpgradeSource(t *testing.T) { root := requireOfflineUpgradePhase(t, "source") testApp := openOfflineUpgradeApp(t, root, true) ctx := testApp.GetContextForDeliverTx(nil).WithBlockTime(time.Now().UTC()) seedV68OfflineDeletedStores(t, testApp, ctx) + seedV68TokenfactoryDenom(t, testApp, ctx) vesting, retained := seedV68OfflineVestingAccounts(t, testApp, ctx) seedV68IBCProposal(t, testApp, ctx, &retained) seedV68UpgradedIBCState(t, testApp, ctx, &retained) @@ -71,9 +73,10 @@ func TestV68OfflineUpgradeSource(t *testing.T) { require.Equal(t, upgradeHeight, plan.Height) moduleVersions := offlineUpgradeModuleVersions(t, testApp) require.Contains(t, moduleVersions, "oracle") + require.Contains(t, moduleVersions, "tokenfactory", "v6.7 module version map does not contain tokenfactory") require.Contains(t, moduleVersions, "vesting", "v6.7 module version map does not contain vesting") // v6.7 dropped the IBC module versions while keeping their stores mounted; - // only oracle and vesting still carry a version into v6.8. + // only oracle, tokenfactory and vesting still carry a version into v6.8. for _, name := range []string{"capability", "ibc", "transfer"} { require.NotContains(t, moduleVersions, name) require.NotNil(t, testApp.GetKey(name)) @@ -99,7 +102,7 @@ func TestV68OfflineUpgradeSource(t *testing.T) { } // TestV68OfflineUpgradeReopen verifies that v6.7 cannot reopen a database whose -// oracle and IBC trees v6.8 deleted. +// oracle, tokenfactory and IBC trees v6.8 deleted. func TestV68OfflineUpgradeReopen(t *testing.T) { root := requireOfflineUpgradePhase(t, "reopen") artifact := readOfflineUpgradeArtifact(t, root) @@ -118,7 +121,7 @@ func TestV68OfflineUpgradeReopen(t *testing.T) { closeOfflineUpgradeApp(t, testApp) }() require.NotNil(t, recovered, - "v6.7 binary reopened a database whose oracle and IBC trees were deleted") + "v6.7 binary reopened a database whose oracle, tokenfactory and IBC trees were deleted") message := fmt.Sprint(recovered) namesDeletedStore := false for _, name := range v68OfflineDeletedStores { @@ -138,6 +141,20 @@ func seedV68OfflineDeletedStores(t *testing.T, testApp *App, ctx sdk.Context) { } } +// seedV68TokenfactoryDenom creates a tokenfactory denom with a transfer +// allowlist and mints a balance of it to its creator. +func seedV68TokenfactoryDenom(t *testing.T, testApp *App, ctx sdk.Context) { + t.Helper() + creator := sdk.AccAddress("v68-factory-creator_") + testApp.AccountKeeper.SetAccount(ctx, testApp.AccountKeeper.NewAccountWithAddress(ctx, creator)) + denom, err := testApp.TokenFactoryKeeper.CreateDenom(ctx, creator.String(), "v68") + require.NoError(t, err) + testApp.BankKeeper.SetDenomAllowList(ctx, denom, banktypes.AllowList{Addresses: []string{creator.String()}}) + minted := sdk.NewCoins(sdk.NewInt64Coin(denom, 1_000)) + require.NoError(t, testApp.BankKeeper.MintCoins(ctx, "tokenfactory", minted)) + require.NoError(t, testApp.BankKeeper.SendCoinsFromModuleToAccount(ctx, "tokenfactory", creator, minted)) +} + // seedV68IBCProposal stores a passed IBC client update proposal, which v6.8 // rewrites as a text proposal. func seedV68IBCProposal(t *testing.T, testApp *App, ctx sdk.Context, retained *offlineUpgradeRetainedState) { diff --git a/app/upgrade_v68_offline_target_test.go b/app/upgrade_v68_offline_target_test.go index 68bb5cbed5..9ebe5e9b97 100644 --- a/app/upgrade_v68_offline_target_test.go +++ b/app/upgrade_v68_offline_target_test.go @@ -22,6 +22,7 @@ import ( banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" distrtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/distribution/types" govtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/gov/types" + paramstypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/params/types" upgradetypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/upgrade/types" "github.com/sei-protocol/sei-chain/sei-db/state_db/sc/memiavl" abci "github.com/sei-protocol/sei-chain/sei-tendermint/abci/types" @@ -40,10 +41,10 @@ const ( ) // v68OfflineRemovedModules are the module version map entries v6.8 deletes. -var v68OfflineRemovedModules = []string{"capability", "ibc", "oracle", "transfer", "vesting"} +var v68OfflineRemovedModules = []string{"capability", "ibc", "oracle", "tokenfactory", "transfer", "vesting"} // v68OfflineDeletedStores are the stores v6.8 deletes from the multistore. -var v68OfflineDeletedStores = []string{"capability", "ibc", "oracle", "transfer"} +var v68OfflineDeletedStores = []string{"capability", "ibc", "oracle", "tokenfactory", "transfer"} var v68OfflineUpgradeBlockTime = time.Unix(1_700_000_000, 0).UTC() func TestV68OfflineUpgradeTarget(t *testing.T) { @@ -134,9 +135,9 @@ func applyV68OfflineUpgradeCrashReplay(t *testing.T, root string, artifact offli // requireV68OfflineMigrated checks a reopened migrated database: the upgrade // is recorded, the retired module versions and stores are gone, the vesting // accounts are rewritten, the retired IBC proposal reads back as a text -// proposal, the upgraded IBC client record is pruned, the IBC voucher balance -// and supply are intact and spendable, and nothing else in the retained -// stores changed. +// proposal, the upgraded IBC client record, the denom allowlists and the +// tokenfactory parameters are pruned, the IBC voucher balance and supply are +// intact and spendable, and nothing else in the retained stores changed. func requireV68OfflineMigrated(t *testing.T, testApp *App, artifact offlineUpgradeArtifact) { t.Helper() requireV68OfflineAppliedName(t, testApp, artifact) @@ -145,6 +146,8 @@ func requireV68OfflineMigrated(t *testing.T, testApp *App, artifact offlineUpgra requireV68OfflineAccountsRewritten(t, testApp, artifact) requireV68OfflineProposalRewritten(t, testApp, artifact.Retained) requireV68OfflineUpgradedIBCStatePruned(t, testApp, artifact.Retained) + requireV68OfflineDenomAllowListsPruned(t, testApp, artifact.Stores[banktypes.StoreKey]) + requireV68OfflineTokenfactoryParamsPruned(t, testApp, artifact.Stores[paramstypes.StoreKey]) requireV68OfflineVoucher(t, testApp, artifact.Retained) requireOfflineUpgradeRetainedStoresExcept(t, testApp, artifact.Stores, v68OfflineTouchedKey(t, artifact)) } @@ -152,8 +155,9 @@ func requireV68OfflineMigrated(t *testing.T, testApp *App, artifact offlineUpgra // v68OfflineTouchedKey reports the retained-store keys the v6.8 upgrade block // is specified to change: the vesting accounts the auth migration rewrites, // the rewritten IBC proposal, the pruned upgraded IBC state, the plan, done -// and version-map entries of the upgrade store, and the bank entries block -// rewards move every block. +// and version-map entries of the upgrade store, the pruned denom allowlists +// and tokenfactory parameters, and the bank entries block rewards move every +// block. func v68OfflineTouchedKey(t *testing.T, artifact offlineUpgradeArtifact) func(storeName string, key []byte) bool { t.Helper() rewritten := make(map[string]struct{}, len(artifact.VestingAccounts)) @@ -174,7 +178,9 @@ func v68OfflineTouchedKey(t *testing.T, artifact offlineUpgradeArtifact) func(st } return len(key) > 0 && (key[0] == upgradetypes.PlanByte || key[0] == upgradetypes.DoneByte || key[0] == upgradetypes.VersionMapByte) case banktypes.StoreKey: - return v68OfflineBlockRewardKey(key) + return v68OfflineBlockRewardKey(key) || bytes.HasPrefix(key, banktypes.DenomAllowListPrefix) + case paramstypes.StoreKey: + return bytes.HasPrefix(key, tokenfactoryParamsPrefix) } return false } @@ -248,11 +254,13 @@ func requireV68OfflineLegacyAccountsStored(t *testing.T, testApp *App, artifact func requireV68OfflineVersionMap(t *testing.T, testApp *App, before []string) { t.Helper() after := offlineUpgradeModuleVersions(t, testApp) - // v6.7 already dropped the IBC module versions, so only oracle and vesting - // are expected to leave the map here; the IBC entries must not be present. + // v6.7 already dropped the IBC module versions, so only oracle, tokenfactory + // and vesting are expected to leave the map here; the IBC entries must not be + // present. removed := offlineUpgradeDifference(before, after) require.Subset(t, v68OfflineRemovedModules, removed, "v6.8 removed an unexpected set of module versions") require.Contains(t, removed, "oracle") + require.Contains(t, removed, "tokenfactory") require.Contains(t, removed, "vesting") require.Empty(t, offlineUpgradeDifference(after, before), "v6.8 added a module version") for _, module := range v68OfflineRemovedModules { @@ -309,6 +317,60 @@ func requireV68OfflineUpgradedIBCStatePruned(t *testing.T, testApp *App, retaine require.False(t, iterator.Valid()) } +// requireV68OfflineDenomAllowListsPruned requires the source phase's bank +// snapshot to hold a denom transfer allowlist and the committed bank store to +// hold none. +func requireV68OfflineDenomAllowListsPruned(t *testing.T, testApp *App, sourceBank map[string]string) { + t.Helper() + recorded := false + for encodedKey := range sourceBank { + key, err := base64.StdEncoding.DecodeString(encodedKey) + require.NoError(t, err) + recorded = recorded || bytes.HasPrefix(key, banktypes.DenomAllowListPrefix) + } + require.True(t, recorded, "the source phase recorded no denom allowlist") + requireV68OfflineNoDenomAllowLists(t, testApp) +} + +// requireV68OfflineNoDenomAllowLists requires the committed bank store to hold +// no denom transfer allowlist. +func requireV68OfflineNoDenomAllowLists(t *testing.T, testApp *App) { + t.Helper() + store := testApp.CommitMultiStore().GetCommitKVStore(testApp.GetKey(banktypes.StoreKey)) + iterator := sdk.KVStorePrefixIterator(store, banktypes.DenomAllowListPrefix) + defer func() { + require.NoError(t, iterator.Close()) + }() + require.False(t, iterator.Valid(), "v6.8 left a denom allowlist in the bank store") +} + +// requireV68OfflineTokenfactoryParamsPruned requires the source phase's params +// snapshot to hold a tokenfactory parameter and the committed params store to +// hold none. +func requireV68OfflineTokenfactoryParamsPruned(t *testing.T, testApp *App, sourceParams map[string]string) { + t.Helper() + recorded := false + for encodedKey := range sourceParams { + key, err := base64.StdEncoding.DecodeString(encodedKey) + require.NoError(t, err) + recorded = recorded || bytes.HasPrefix(key, tokenfactoryParamsPrefix) + } + require.True(t, recorded, "the source phase recorded no tokenfactory parameter") + requireV68OfflineNoTokenfactoryParams(t, testApp) +} + +// requireV68OfflineNoTokenfactoryParams requires the committed params store to +// hold no tokenfactory parameter. +func requireV68OfflineNoTokenfactoryParams(t *testing.T, testApp *App) { + t.Helper() + store := testApp.CommitMultiStore().GetCommitKVStore(testApp.GetKey(paramstypes.StoreKey)) + iterator := sdk.KVStorePrefixIterator(store, tokenfactoryParamsPrefix) + defer func() { + require.NoError(t, iterator.Close()) + }() + require.False(t, iterator.Valid(), "v6.8 left a tokenfactory parameter in the params store") +} + func requireV68OfflineVoucher(t *testing.T, testApp *App, retained offlineUpgradeRetainedState) { t.Helper() ctx, _ := offlineUpgradeReadContext(testApp, testApp.LastBlockHeight()).CacheContext() @@ -524,6 +586,7 @@ func testV68OfflineUpgradeTargetSnapshot(t *testing.T) { sourceHeight := testApp.LastBlockHeight() beforeVersions := offlineUpgradeModuleVersions(t, testApp) require.Contains(t, beforeVersions, "oracle") + require.Contains(t, beforeVersions, "tokenfactory") require.Contains(t, beforeVersions, "vesting", "%s is not a pre-v6.8 snapshot: module version map is missing vesting", home) legacy := v68OfflineLegacyVestingAccounts(t, testApp, offlineUpgradeContext(testApp, sourceHeight, chainID)) @@ -549,6 +612,8 @@ func testV68OfflineUpgradeTargetSnapshot(t *testing.T) { defer closeOfflineUpgradeApp(t, reopened) requireV68OfflineVersionMap(t, reopened, beforeVersions) requireV68OfflineNoRetiredProposals(t, reopened) + requireV68OfflineNoDenomAllowLists(t, reopened) + requireV68OfflineNoTokenfactoryParams(t, reopened) ctx := offlineUpgradeContext(reopened, reopened.LastBlockHeight(), chainID) require.Empty(t, v68OfflineLegacyVestingAccounts(t, reopened, ctx), "accounts are still stored under a vesting type") for _, address := range legacy { diff --git a/app/upgrade_v68_test.go b/app/upgrade_v68_test.go index fda271f968..a10969a2bd 100644 --- a/app/upgrade_v68_test.go +++ b/app/upgrade_v68_test.go @@ -4,6 +4,7 @@ package app_test import ( "encoding/json" + "fmt" "strconv" "strings" "testing" @@ -11,6 +12,7 @@ import ( "github.com/sei-protocol/sei-chain/app" "github.com/sei-protocol/sei-chain/app/retiredoracle" + "github.com/sei-protocol/sei-chain/app/retiredtokenfactory" "github.com/sei-protocol/sei-chain/app/retiredvesting" codectypes "github.com/sei-protocol/sei-chain/sei-cosmos/codec/types" "github.com/sei-protocol/sei-chain/sei-cosmos/crypto/keys/secp256k1" @@ -18,7 +20,9 @@ import ( "github.com/sei-protocol/sei-chain/sei-cosmos/x/auth/signing" authtestutil "github.com/sei-protocol/sei-chain/sei-cosmos/x/auth/testutil" authtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/auth/types" + banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" govtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/gov/types" + paramstypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/params/types" upgradetypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/upgrade/types" abci "github.com/sei-protocol/sei-chain/sei-tendermint/abci/types" "github.com/sei-protocol/sei-chain/testutil/processblock" @@ -28,18 +32,20 @@ import ( "google.golang.org/protobuf/encoding/protowire" ) -// v6.8 removes the oracle and vesting modules. The store loader deletes the -// oracle store at the upgrade height, and the handler deletes both modules' -// version-map entries. Vesting owned no store: its state is the accounts it -// wrote to the auth account store, which the auth 3 to 4 migration rewrites as -// the base accounts they embed. These tests cover the rewrite of every vesting -// account type, spending a balance a schedule had locked, the messages both -// modules served, genesis export over the migrated store, and the handler -// itself. +// v6.8 removes the oracle, tokenfactory and vesting modules. The store loader +// deletes the oracle, tokenfactory and retired IBC stores at the upgrade height, +// and the handler deletes the removed modules' version-map entries, the denom +// transfer allowlists tokenfactory kept in the bank store, and its parameters in +// the params store. Vesting owned no store: its state is the accounts it wrote +// to the auth account store, which the auth 3 to 4 migration rewrites as the +// base accounts they embed. These tests cover the rewrite of every vesting +// account type, spending a balance a schedule had locked, the messages the +// removed modules served, the allowlist and parameter pruning, genesis export +// over the migrated store, and the handler itself. // v68RemovedStoreModules are the module version map entries the v6.8 handler // deletes along with their stores. -var v68RemovedStoreModules = []string{"capability", "ibc", "oracle", "transfer"} +var v68RemovedStoreModules = []string{"capability", "ibc", "oracle", "tokenfactory", "transfer"} const ( v68UpgradeName = "v6.8" @@ -49,6 +55,8 @@ const ( v68VestingEndTime int64 = 32_503_680_000 v68VestingBalance int64 = 1_000_000_000 v68VestingModule = "vesting" + // v68TokenfactoryVersionBefore is the tokenfactory consensus version v6.7 records. + v68TokenfactoryVersionBefore uint64 = 5 // v68AuthVersionBefore and v68AuthVersion are the auth consensus versions // on either side of the upgrade. v68AuthVersionBefore uint64 = 3 @@ -105,12 +113,14 @@ type v68VestingFixture struct { } // seedV67VersionMap records in the version map what every chain upgrading from -// v6.7 carries: auth at its v6.7 consensus version, oracle, and vesting. +// v6.7 carries: auth and tokenfactory at their v6.7 consensus versions, oracle, +// and vesting. func seedV67VersionMap(t *testing.T, a *processblock.App) { t.Helper() versionMap := a.UpgradeKeeper.GetModuleVersionMap(a.Ctx()) versionMap[authtypes.ModuleName] = v68AuthVersionBefore versionMap[retiredoracle.ModuleName] = 1 + versionMap[retiredtokenfactory.ModuleName] = v68TokenfactoryVersionBefore versionMap[v68VestingModule] = 1 a.UpgradeKeeper.SetModuleVersionMap(a.Ctx(), versionMap) } @@ -159,7 +169,14 @@ func seedV67VestingState(t *testing.T, a *processblock.App) []v68VestingFixture // v68AccountEntries returns every entry under the account prefix of store. func v68AccountEntries(t *testing.T, store sdk.KVStore) map[string][]byte { t.Helper() - iterator := sdk.KVStorePrefixIterator(store, authtypes.AddressStoreKeyPrefix) + return v68PrefixEntries(t, store, authtypes.AddressStoreKeyPrefix) +} + +// v68PrefixEntries returns every entry of store under prefix, or every entry of +// store when prefix is empty. +func v68PrefixEntries(t *testing.T, store sdk.KVStore, prefix []byte) map[string][]byte { + t.Helper() + iterator := sdk.KVStorePrefixIterator(store, prefix) defer func() { require.NoError(t, iterator.Close()) }() @@ -238,14 +255,16 @@ func TestV68RewritesVestingAccountsAsBaseAccounts(t *testing.T) { versionsAfter := a.UpgradeKeeper.GetModuleVersionMap(a.Ctx()) require.NotContains(t, versionsAfter, retiredoracle.ModuleName) + require.NotContains(t, versionsAfter, retiredtokenfactory.ModuleName) require.NotContains(t, versionsAfter, v68VestingModule) require.Equal(t, v68AuthVersion, versionsAfter[authtypes.ModuleName]) delete(versionsBefore, retiredoracle.ModuleName) + delete(versionsBefore, retiredtokenfactory.ModuleName) delete(versionsBefore, v68VestingModule) delete(versionsBefore, authtypes.ModuleName) delete(versionsAfter, authtypes.ModuleName) require.Equal(t, versionsBefore, versionsAfter, - "v6.8 changed a module version other than removing oracle and vesting and moving auth") + "v6.8 changed a module version other than removing oracle, tokenfactory and vesting and moving auth") } // TestV68ConvertedAccountSpendsTheBalanceItsScheduleLocked delivers a bank send @@ -388,6 +407,183 @@ func TestV68RejectsTheVestingMessageWithoutCharging(t *testing.T) { require.Equal(t, retiredvesting.ErrDeprecated.Codespace(), check.Codespace) } +// TestV68RejectsTokenfactoryTxsWithoutCharging delivers and checks a signed +// transaction of every tokenfactory message after v6.8. Each decodes as its +// retired type, which fails validation, so it is refused before any fee is taken. +func TestV68RejectsTokenfactoryTxsWithoutCharging(t *testing.T) { + a := newV68Chain(t) + signer := a.NewSignableAccount("v68/tokenfactory-admin") + a.FundAccount(signer, v68VestingBalance) + a.RunBlock([]signing.Tx{}) + applyV68ToCommitStore(t, a) + a.RunBlock([]signing.Tx{}) + + denom := "factory/" + signer.String() + "/v68" + retired := []struct { + name string + msg sdk.Msg + }{ + {"create denom", &retiredtokenfactory.MsgCreateDenom{Sender: signer.String(), Subdenom: "v68"}}, + {"update denom", &retiredtokenfactory.MsgUpdateDenom{Sender: signer.String(), Denom: denom, AllowList: &banktypes.AllowList{Addresses: []string{signer.String()}}}}, + {"mint", &retiredtokenfactory.MsgMint{Sender: signer.String(), Amount: sdk.NewInt64Coin(denom, 1)}}, + {"burn", &retiredtokenfactory.MsgBurn{Sender: signer.String(), Amount: sdk.NewInt64Coin(denom, 1)}}, + {"change admin", &retiredtokenfactory.MsgChangeAdmin{Sender: signer.String(), Denom: denom, NewAdmin: signer.String()}}, + {"set denom metadata", &retiredtokenfactory.MsgSetDenomMetadata{Sender: signer.String(), Metadata: banktypes.Metadata{ + Base: denom, Display: denom, DenomUnits: []*banktypes.DenomUnit{{Denom: denom}}, + }}}, + } + for _, retired := range retired { + t.Run(retired.name, func(t *testing.T) { + tx := a.Sign(signer, v68TxFee, retired.msg) + balanceBefore := a.BankKeeper.GetBalance(a.Ctx(), signer, "usei") + + results := a.RunBlockDetailed([]signing.Tx{tx}) + require.Len(t, results, 1) + require.Equal(t, retiredtokenfactory.ErrDeprecated.ABCICode(), results[0].Code, results[0].Log) + require.Equal(t, retiredtokenfactory.ErrDeprecated.Codespace(), results[0].Codespace) + require.Equal(t, balanceBefore, a.BankKeeper.GetBalance(a.Ctx(), signer, "usei"), + "the refused tokenfactory message was charged a fee") + + txBytes, err := processblock.TxConfig.TxEncoder()(tx) + require.NoError(t, err) + check := a.CheckTx(t.Context(), &abci.RequestCheckTxV2{Tx: txBytes}) + require.Equal(t, retiredtokenfactory.ErrDeprecated.ABCICode(), check.Code, check.Log) + require.Equal(t, retiredtokenfactory.ErrDeprecated.Codespace(), check.Codespace) + }) + } +} + +// v68DenomAllowListKey returns the bank-store key under which tokenfactory kept +// the transfer allowlist of denom. +func v68DenomAllowListKey(denom string) []byte { + return append(append([]byte{0x11}, denom...), denom...) +} + +// v68SeedDenomAllowList stores a transfer allowlist for denom naming addresses, +// the way tokenfactory wrote one. +func v68SeedDenomAllowList(t *testing.T, a *processblock.App, denom string, addresses ...string) { + t.Helper() + allowList, err := (&banktypes.AllowList{Addresses: addresses}).Marshal() + require.NoError(t, err) + a.Ctx().KVStore(a.GetKey(banktypes.StoreKey)).Set(v68DenomAllowListKey(denom), allowList) +} + +// TestV68PrunesDenomAllowLists pins that every denom transfer allowlist is +// deleted from the bank store, while the balance and metadata of the denoms they +// restricted are kept. +func TestV68PrunesDenomAllowLists(t *testing.T) { + a := newV68Chain(t) + ctx := a.Ctx() + holder := a.NewAccount() + restricted := "factory/" + holder.String() + "/restricted" + unrestricted := "factory/" + holder.String() + "/unrestricted" + v68SeedDenomAllowList(t, a, restricted, holder.String()) + v68SeedDenomAllowList(t, a, unrestricted) + a.FundAccountWithDenom(holder, 100, restricted) + metadata := banktypes.Metadata{Base: restricted, Display: restricted, DenomUnits: []*banktypes.DenomUnit{{Denom: restricted}}} + a.BankKeeper.SetDenomMetaData(ctx, metadata) + + applyV68(t, a) + + iterator := sdk.KVStorePrefixIterator(ctx.KVStore(a.GetKey(banktypes.StoreKey)), []byte{0x11}) + defer iterator.Close() + require.False(t, iterator.Valid(), "v6.8 left a denom allowlist in the bank store") + require.Equal(t, sdk.NewInt64Coin(restricted, 100), a.BankKeeper.GetBalance(ctx, holder, restricted)) + stored, found := a.BankKeeper.GetDenomMetaData(ctx, restricted) + require.True(t, found) + require.Equal(t, metadata, stored) +} + +// TestV68SendsADenomItsAllowListRestricted delivers, after v6.8, a bank send of +// a factory denom to an address its allowlist did not name. +func TestV68SendsADenomItsAllowListRestricted(t *testing.T) { + a := newV68Chain(t) + holder := a.NewSignableAccount("v68/allowlisted-holder") + a.FundAccount(holder, v68VestingBalance) + denom := "factory/" + holder.String() + "/restricted" + a.FundAccountWithDenom(holder, 100, denom) + v68SeedDenomAllowList(t, a, denom, holder.String()) + recipient := a.NewAccount() + a.RunBlock([]signing.Tx{}) + + applyV68ToCommitStore(t, a) + a.RunBlock([]signing.Tx{}) + + results := a.RunBlockDetailed([]signing.Tx{ + a.Sign(holder, v68TxFee, &banktypes.MsgSend{ + FromAddress: holder.String(), + ToAddress: recipient.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin(denom, 40)), + }), + }) + require.Len(t, results, 1) + require.Equal(t, uint32(abci.CodeTypeOK), results[0].Code, results[0].Log) + require.Equal(t, sdk.NewInt64Coin(denom, 40), a.BankKeeper.GetBalance(a.Ctx(), recipient, denom)) + require.Equal(t, sdk.NewInt64Coin(denom, 60), a.BankKeeper.GetBalance(a.Ctx(), holder, denom)) +} + +// TestV68DenomAllowListPruneIsBounded pins that v6.8 deletes at most +// app.RetiredPrefixDeleteLimit denom transfer allowlists, in key order, and that +// an allowlist it leaves in the bank store does not restrict a send of its denom. +func TestV68DenomAllowListPruneIsBounded(t *testing.T) { + a := newV68Chain(t) + holder := a.NewSignableAccount("v68/overflow-allowlisted-holder") + a.FundAccount(holder, v68VestingBalance) + denoms := make([]string, app.RetiredPrefixDeleteLimit+1) + for i := range denoms { + denoms[i] = fmt.Sprintf("factory/%s/overflow%04d", holder, i) + v68SeedDenomAllowList(t, a, denoms[i], holder.String()) + } + kept := denoms[len(denoms)-1] + a.FundAccountWithDenom(holder, 100, kept) + recipient := a.NewAccount() + a.RunBlock([]signing.Tx{}) + + applyV68ToCommitStore(t, a) + a.RunBlock([]signing.Tx{}) + + left := v68PrefixEntries(t, a.Ctx().KVStore(a.GetKey(banktypes.StoreKey)), []byte{0x11}) + require.Len(t, left, 1, "v6.8 did not delete exactly app.RetiredPrefixDeleteLimit denom allowlists") + require.Contains(t, left, string(v68DenomAllowListKey(kept))) + + results := a.RunBlockDetailed([]signing.Tx{ + a.Sign(holder, v68TxFee, &banktypes.MsgSend{ + FromAddress: holder.String(), + ToAddress: recipient.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin(kept, 40)), + }), + }) + require.Len(t, results, 1) + require.Equal(t, uint32(abci.CodeTypeOK), results[0].Code, results[0].Log) + require.Equal(t, sdk.NewInt64Coin(kept, 40), a.BankKeeper.GetBalance(a.Ctx(), recipient, kept)) +} + +// TestV68PrunesTokenfactoryParams pins that every entry of the tokenfactory +// parameter subspace is deleted from the params store and that nothing else in +// the store changes. The subspace holds the parameter v6.7 keeps and a creation +// fee an older tokenfactory version left behind. +func TestV68PrunesTokenfactoryParams(t *testing.T) { + a := newV68Chain(t) + store := a.Ctx().KVStore(a.GetKey(paramstypes.StoreKey)) + retired := map[string]string{ + "tokenfactory/allowlistmaxsize": "2000", + "tokenfactory/DenomCreationFee": "[]", + } + for key, value := range retired { + store.Set([]byte(key), []byte(value)) + } + store.Set([]byte("tokenfactoryless"), []byte("unrelated")) + kept := v68PrefixEntries(t, store, nil) + for key := range retired { + delete(kept, key) + } + + applyV68(t, a) + + require.Equal(t, kept, v68PrefixEntries(t, store, nil), + "v6.8 changed the params store beyond deleting the tokenfactory subspace") +} + // TestV68RewritesRetiredIBCProposals pins that a stored proposal whose content // type lives under an IBC protobuf package reads back as a text proposal with // the original title and description, with its status, deposits and votes @@ -524,14 +720,16 @@ func TestV68CrossVersion(t *testing.T) { upgradetest.RunCrossVersion(t, seedV67State, verifyV68State) } -// seedV67State records the v6.7 version map, which carries oracle and vesting -// with auth at consensus version 3, requires v6.7 to serve the vesting command, -// and delivers a bank send before the upgrade. +// seedV67State records the v6.7 version map, which carries oracle, tokenfactory +// and vesting with auth at consensus version 3, requires v6.7 to serve the +// vesting command, and delivers a bank send before the upgrade. func seedV67State(t *testing.T, chain *upgradetest.CrossVersion) { require.Equal(t, v68UpgradeName, chain.UpgradeName(t)) versions := v68ModuleVersions(t, chain) require.Contains(t, versions, retiredoracle.ModuleName, "v6.7 module version map does not carry oracle") + require.Equal(t, v68TokenfactoryVersionBefore, versions[retiredtokenfactory.ModuleName], + "v6.7 module version map does not carry tokenfactory") require.Equal(t, uint64(1), versions[v68VestingModule], "v6.7 module version map does not carry vesting") require.Equal(t, v68AuthVersionBefore, versions[authtypes.ModuleName]) require.NotEmpty(t, chain.QueryStore(t, upgradetypes.StoreKey, v68ModuleVersionKey(v68VestingModule)), @@ -572,13 +770,14 @@ func verifyV68State(t *testing.T, chain *upgradetest.CrossVersion) { want[name] = version } delete(want, retiredoracle.ModuleName) + delete(want, retiredtokenfactory.ModuleName) delete(want, v68VestingModule) want[authtypes.ModuleName] = v68AuthVersion want[govtypes.ModuleName] = v68GovVersion after := v68ModuleVersions(t, chain) chain.Record(t, "module_versions_after", after) require.Equal(t, want, after, - "v6.8 changed the version map beyond removing oracle and vesting, moving auth to %d and moving gov to %d", + "v6.8 changed the version map beyond removing oracle, tokenfactory and vesting, moving auth to %d and moving gov to %d", v68AuthVersion, v68GovVersion) require.Empty(t, chain.QueryStore(t, upgradetypes.StoreKey, v68ModuleVersionKey(v68VestingModule)), "v6.8 upgrade store still carries the vesting version-map entry") @@ -590,7 +789,10 @@ func verifyV68State(t *testing.T, chain *upgradetest.CrossVersion) { "http://127.0.0.1:26657/abci_query?path=%2Fstore%2Foracle%2Fkey") require.NotContains(t, oracleStore.Combined(), retiredoracle.ErrDeprecated.Error()) require.Contains(t, oracleStore.Combined(), "no such store: oracle") - for _, store := range []string{"ibc", "transfer", "capability"} { + tokenfactoryCommand := chain.Seid("", "q", retiredtokenfactory.ModuleName) + require.Error(t, tokenfactoryCommand.Err) + require.Contains(t, tokenfactoryCommand.Combined(), `unknown command "tokenfactory"`) + for _, store := range []string{"ibc", "transfer", "capability", retiredtokenfactory.ModuleName} { raw := chain.Binary("", "curl", "-s", "http://127.0.0.1:26657/abci_query?path=%2Fstore%2F"+store+"%2Fkey") require.Contains(t, raw.Combined(), "no such store: "+store) diff --git a/app/upgrades.go b/app/upgrades.go index 96bcb870bc..cdd0d07584 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -7,10 +7,13 @@ import ( "strings" "github.com/sei-protocol/sei-chain/app/retiredoracle" + "github.com/sei-protocol/sei-chain/app/retiredtokenfactory" codectypes "github.com/sei-protocol/sei-chain/sei-cosmos/codec/types" sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" "github.com/sei-protocol/sei-chain/sei-cosmos/types/module" + banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" govtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/gov/types" + paramstypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/params/types" upgradetypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/upgrade/types" "golang.org/x/mod/semver" "google.golang.org/protobuf/encoding/protowire" @@ -22,7 +25,11 @@ var retiredIBCStores = []string{"capability", "ibc", "transfer"} // v68DeletedStores are the KV stores deleted from the multistore at the v6.8 // upgrade height. Their module version map entries go with them. -var v68DeletedStores = append([]string{retiredoracle.ModuleName}, retiredIBCStores...) +var v68DeletedStores = append([]string{retiredoracle.ModuleName, retiredtokenfactory.ModuleName}, retiredIBCStores...) + +// tokenfactoryParamsPrefix is the params-store prefix of the tokenfactory +// parameter subspace. +var tokenfactoryParamsPrefix = []byte(retiredtokenfactory.ModuleName + "/") // retiredIBCProposalTypeURLPrefix matches governance proposal content types // whose decoders no longer exist. @@ -35,6 +42,10 @@ const retiredIBCProposalTypeURLPrefix = "/ibc." // block's work independent of how many proposals are submitted before it. const RetiredIBCProposalIDLimit uint64 = 1000 +// RetiredPrefixDeleteLimit is the most keys the v6.8 upgrade deletes under one +// retired store prefix. +const RetiredPrefixDeleteLimit = 1000 + // upgradedIBCStateKeyPrefix is the upgrade-store prefix under which the cosmos // upgrade module recorded planned IBC client state before IBC was retired. const upgradedIBCStateKeyPrefix = "upgradedIBCState/" @@ -156,6 +167,8 @@ func (app *App) RegisterUpgradeHandlers() { app.UpgradeKeeper.DeleteModuleVersion(ctx, feegrantModuleName) app.UpgradeKeeper.DeleteModuleVersion(ctx, vestingModuleName) app.pruneUpgradedIBCState(ctx) + app.pruneDenomAllowLists(ctx) + app.pruneTokenfactoryParams(ctx) return newVM, nil } @@ -246,10 +259,25 @@ func (app *App) pruneUpgradedIBCState(ctx sdk.Context) { deleteByPrefix(ctx.KVStore(app.GetKey(upgradetypes.StoreKey)), []byte(upgradedIBCStateKeyPrefix)) } +// pruneDenomAllowLists deletes the denom transfer allowlists tokenfactory kept in +// the bank store, up to RetiredPrefixDeleteLimit of them. +func (app *App) pruneDenomAllowLists(ctx sdk.Context) { + deleteByPrefix(ctx.KVStore(app.GetKey(banktypes.StoreKey)), banktypes.DenomAllowListPrefix) +} + +// pruneTokenfactoryParams removes every parameter of the tokenfactory subspace from the params store. +func (app *App) pruneTokenfactoryParams(ctx sdk.Context) { + deleteByPrefix(ctx.KVStore(app.GetKey(paramstypes.StoreKey)), tokenfactoryParamsPrefix) +} + +// deleteByPrefix deletes the first RetiredPrefixDeleteLimit keys under prefix in +// store and leaves any others in place. func deleteByPrefix(store sdk.KVStore, prefix []byte) { iterator := sdk.KVStorePrefixIterator(store, prefix) var keys [][]byte - for ; iterator.Valid(); iterator.Next() { + // Anyone may have written keys under the prefix before the upgrade, so the + // upgrade block's work must not grow with how many there are. + for ; iterator.Valid() && len(keys) < RetiredPrefixDeleteLimit; iterator.Next() { keys = append(keys, iterator.Key()) } if err := iterator.Close(); err != nil { diff --git a/contracts/test/EVMPrecompileTest.js b/contracts/test/EVMPrecompileTest.js index a4fe4af098..8aa60a38fe 100755 --- a/contracts/test/EVMPrecompileTest.js +++ b/contracts/test/EVMPrecompileTest.js @@ -4,7 +4,7 @@ const fs = require('fs'); const path = require('path'); const { expectRevert } = require('@openzeppelin/test-helpers'); -const { setupSigners, getAdmin, deployWasm, storeWasm, execute, isDocker, ABI, createTokenFactoryTokenAndMint, getSeiBalance, rawHttpDebugTraceWithCallTracer, proposeParamChange} = require("./lib"); +const { setupSigners, getAdmin, deployWasm, storeWasm, execute, isDocker, ABI, fundSeiAddress, getSeiBalance, rawHttpDebugTraceWithCallTracer, proposeParamChange} = require("./lib"); function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); @@ -355,8 +355,9 @@ describe("EVM Precompile Tester", function () { accounts = await setupSigners(await hre.ethers.getSigners()) admin = await getAdmin() - const random_num = Math.floor(Math.random() * 10000) - denom = await createTokenFactoryTokenAndMint(`native-pointer-test-${random_num}`, 1000, accounts[0].seiAddress); + // The docker devnet genesis funds the admin key with uatom. + denom = "uatom" + await fundSeiAddress(accounts[0].seiAddress, "1000", denom) }); it("Wasm Precompile Instantiate", async function () { diff --git a/contracts/test/lib.js b/contracts/test/lib.js index e353a24232..61c44f8da6 100644 --- a/contracts/test/lib.js +++ b/contracts/test/lib.js @@ -376,53 +376,6 @@ async function rawHttpDebugTraceWithCallTracer(txHash) { return response.data; } -async function createTokenFactoryTokenAndMint(name, amount, recipient, from=adminKeyName) { - const fromSeiAddr = await getKeySeiAddress(from) - // Tokenfactory denom is deterministic: factory//. - const token_denom = `factory/${fromSeiAddr}/${name}` - const target = BigInt(amount) - - // Step 1: create-denom. Wait for the denom to exist before submitting - // the next tx — each `seid tx` reads the node's committed account - // sequence, so consecutive -b sync submissions from the same key - // without a between-commit wait construct duplicate-sequence txs and - // get rejected with "account sequence mismatch". - const create_cmd = `seid tx tokenfactory create-denom ${name} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode sync -o json` - const response = JSON.parse(await execute(create_cmd)) - if (response.code !== 0) throw new Error(`create-denom rejected: ${response.raw_log}`) - await waitForCondition( - async () => { - try { - const out = await execute(`seid query tokenfactory denom-authority-metadata ${token_denom} --output json`) - // For a non-existent denom this query returns {"authority_metadata":{"admin":""}} - // (no error). Only a non-empty admin indicates the create-denom is committed. - return (JSON.parse(out).authority_metadata?.admin || '') !== '' - } catch (e) { return false } - }, - `denom ${token_denom} to be created`, - ) - - // Step 2: mint to ${from}. Wait until the creator holds the minted - // amount before the bank send, for the same sequence reason. - const mint_cmd = `seid tx tokenfactory mint ${amount}${token_denom} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode sync -o json` - const mintResp = JSON.parse(await execute(mint_cmd)) - if (mintResp.code !== 0) throw new Error(`mint rejected: ${mintResp.raw_log}`) - await waitForCondition( - async () => (await getSeiBalanceBigInt(fromSeiAddr, token_denom)) >= target, - `${from} ${token_denom} balance >= ${target}`, - ) - - // Step 3: bank send to recipient. Wait for the recipient to hold the amount. - const send_cmd = `seid tx bank send ${from} ${recipient} ${amount}${token_denom} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode sync -o json` - const sendResp = JSON.parse(await execute(send_cmd)) - if (sendResp.code !== 0) throw new Error(`bank send rejected: ${sendResp.raw_log}`) - await waitForCondition( - async () => (await getSeiBalanceBigInt(recipient, token_denom)) >= target, - `${recipient} ${token_denom} balance >= ${target}`, - ) - return token_denom -} - async function getChainId() { const nodeUrl = 'http://localhost:8545'; const response = await axios.post(nodeUrl, { @@ -1025,7 +978,6 @@ module.exports = { storeWasm, deployWasm, instantiateWasm, - createTokenFactoryTokenAndMint, getChainId, getGasPrice, execute, diff --git a/evmrpc/tests/regression_test.go b/evmrpc/tests/regression_test.go index f1792e0a64..0456616aa2 100644 --- a/evmrpc/tests/regression_test.go +++ b/evmrpc/tests/regression_test.go @@ -266,7 +266,7 @@ func Test0xc2da776841226a9837bc3bb506fcf487e75a7e7787ab1084896251114d6bd7f9(t *t "v5.7.5", "0x933d4", "", - false, + true, ) } @@ -344,9 +344,9 @@ func Test0x29b9a9764a27ba65139ccf06ef51e18358a63dfe143bfa6a16a891127cfc8ab6(t *t testTx(t, "0x29b9a9764a27ba65139ccf06ef51e18358a63dfe143bfa6a16a891127cfc8ab6", "v6.0.2", - "0x92986", - "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - false, + "0x92cc1", + "", + true, ) } @@ -364,9 +364,9 @@ func Test0x534a7d8dac27858aff75623792fee542dd7cec2539c2ddac92749e85bdc08e84(t *t testTx(t, "0x534a7d8dac27858aff75623792fee542dd7cec2539c2ddac92749e85bdc08e84", "v6.0.3", - "0x921c1", - "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - false, + "0x924f2", + "", + true, ) } diff --git a/giga/deps/xbank/keeper/keeper_test.go b/giga/deps/xbank/keeper/keeper_test.go index 182f204277..c249240bae 100644 --- a/giga/deps/xbank/keeper/keeper_test.go +++ b/giga/deps/xbank/keeper/keeper_test.go @@ -21,13 +21,12 @@ import ( ) const ( - fooDenom = "foo" - barDenom = "bar" - factoryDenomPrefix = "factory" - initialPower = int64(100) - holder = "holder" - multiPerm = "multiple permissions account" - randomPerm = "random permission" + fooDenom = "foo" + barDenom = "bar" + initialPower = int64(100) + holder = "holder" + multiPerm = "multiple permissions account" + randomPerm = "random permission" ) var ( @@ -46,10 +45,6 @@ func newFooCoin(amt int64) sdk.Coin { return sdk.NewInt64Coin(fooDenom, amt) } -func newFactoryFooCoin(address sdk.AccAddress, amt int64) sdk.Coin { - return sdk.NewInt64Coin(fmt.Sprintf("%s/%s/%s", factoryDenomPrefix, address, fooDenom), amt) -} - func newBarCoin(amt int64) sdk.Coin { return sdk.NewInt64Coin(barDenom, amt) } @@ -290,26 +285,6 @@ func (suite *IntegrationTestSuite) TestSendCoins() { suite.Require().NoError(app.GigaBankKeeper.SendCoins(ctx, addr1, addr2, sendAmt)) } -func (suite *IntegrationTestSuite) TestSendCoinsWithAllowList() { - app, ctx := suite.app, suite.ctx - addr1 := sdk.AccAddress("addr1_______________") - acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1) - app.AccountKeeper.SetAccount(ctx, acc1) - factoryCoin := newFactoryFooCoin(addr1, 100) - balances := sdk.NewCoins(factoryCoin, newBarCoin(50)) - suite.Require().NoError(apptesting.FundAccount(app.GigaBankKeeper, ctx, addr1, balances)) - - addr2 := sdk.AccAddress("addr2_______________") - acc2 := app.AccountKeeper.NewAccountWithAddress(ctx, addr2) - app.AccountKeeper.SetAccount(ctx, acc2) - - app.GigaBankKeeper.SetDenomAllowList(ctx, factoryCoin.Denom, - types.AllowList{Addresses: []string{addr1.String(), addr2.String()}}) - - sendAmt := sdk.NewCoins(newFactoryFooCoin(addr1, 40), newBarCoin(25)) - suite.Require().NoError(app.GigaBankKeeper.SendCoins(ctx, addr1, addr2, sendAmt)) -} - func (suite *IntegrationTestSuite) TestSendCoinsModuleToAccount() { // add module accounts to supply keeper ctx := suite.ctx @@ -436,180 +411,6 @@ func (suite *IntegrationTestSuite) TestSetDenomMetaData() { suite.Require().Equal(metadata[1].GetDenomUnits()[1].GetAliases(), actualMetadata.GetDenomUnits()[1].GetAliases()) } -func (suite *IntegrationTestSuite) TestSetAllowList() { - app, ctx := suite.app, suite.ctx - - allowList := types.AllowList{Addresses: []string{"addr1", "addr2"}} - ownerAddress := sdk.AccAddress("owner") - denom := "factory/" + ownerAddress.String() + "/Test" - - app.GigaBankKeeper.SetDenomAllowList(ctx, denom, allowList) - - actualAllowList := app.GigaBankKeeper.GetDenomAllowList(ctx, denom) - suite.Require().Equal(allowList, actualAllowList) -} - -func (suite *IntegrationTestSuite) TestBaseKeeper_IsAllowedToSendCoins() { - type CoinToAllowList struct { - coin sdk.Coin - allowList types.AllowList - } - type args struct { - addr sdk.AccAddress - coinsToAllowList []CoinToAllowList - } - tests := []struct { - name string - args args - isAllowed bool - }{ - { - name: "Allowed for for empty coins", - args: args{ - addr: sdk.AccAddress{}, - coinsToAllowList: []CoinToAllowList{ - {coin: sdk.Coin{}}, - }, - }, - isAllowed: true, - }, - { - name: "allowed for to transfer with a non-factory coin", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin("test", 100), - }, - }, - }, - isAllowed: true, - }, - { - name: "allowed with a factory coin with no allow list", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin( - fmt.Sprintf("factory/%s/test", sdk.AccAddress("from")), 100), - }, - }, - }, - isAllowed: true, - }, - { - name: "allowed with a factory coin with empty allow list", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin( - fmt.Sprintf("factory/%s/test", sdk.AccAddress("from")), 100), - allowList: types.AllowList{}, - }, - }, - }, - isAllowed: true, - }, - { - name: "not allowed to transfer coins for denom if not in allowlist", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin(fmt.Sprintf("factory/%s/test", sdk.AccAddress("from")), 100), - allowList: types.AllowList{ - Addresses: []string{sdk.AccAddress("other").String()}, - }, - }, - }, - }, - isAllowed: false, - }, - { - name: "allowed to transfer for denom", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin(fmt.Sprintf("factory/%s/test", sdk.AccAddress("from")), 100), - allowList: types.AllowList{ - Addresses: []string{sdk.AccAddress("from").String(), sdk.AccAddress("to").String()}, - }, - }, - }, - }, - isAllowed: true, - }, - { - name: "allowed for one coin but not allowed for another coin", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin(fmt.Sprintf("factory/%s/test", sdk.AccAddress("from")), 100), - allowList: types.AllowList{ - Addresses: []string{sdk.AccAddress("from").String(), sdk.AccAddress("to").String()}, - }, - }, - { - coin: sdk.NewInt64Coin(fmt.Sprintf("factory/%s/test2", sdk.AccAddress("from")), 100), - allowList: types.AllowList{ - Addresses: []string{sdk.AccAddress("other").String(), sdk.AccAddress("yetanother").String()}, - }, - }, - }, - }, - isAllowed: false, - }, - { - name: "not allowed for first coin but allowed for another coin", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin(fmt.Sprintf("factory/%s/test", sdk.AccAddress("from")), 100), - allowList: types.AllowList{ - Addresses: []string{sdk.AccAddress("other").String(), sdk.AccAddress("yetanother").String()}, - }, - }, - { - coin: sdk.NewInt64Coin(fmt.Sprintf("factory/%s/test2", sdk.AccAddress("from")), 100), - allowList: types.AllowList{ - Addresses: []string{sdk.AccAddress("from").String(), sdk.AccAddress("to").String()}, - }, - }, - }, - }, - isAllowed: false, - }, - } - - for _, tt := range tests { - suite.Run(tt.name, func() { - app, ctx := suite.app, suite.ctx - coins := sdk.NewCoins() - for _, coinToAllowList := range tt.args.coinsToAllowList { - if coinToAllowList.coin.Denom != "" { - coins = coins.Add(coinToAllowList.coin) - if coinToAllowList.allowList.Addresses != nil { - app.GigaBankKeeper.SetDenomAllowList(ctx, coinToAllowList.coin.Denom, coinToAllowList.allowList) - } - } - } - denomToAllowedAddressesCache := make(map[string]keeper.AllowedAddresses) - isAllowed := - app.GigaBankKeeper.IsInDenomAllowList(ctx, tt.args.addr, coins, denomToAllowedAddressesCache) - - // Use suite.Require to assert the results - suite.Require().Equal(tt.isAllowed, isAllowed, - fmt.Errorf("IsInDenomAllowList() isAllowed = %v, want %v", - isAllowed, tt.isAllowed)) - }) - } -} - func (suite *IntegrationTestSuite) TestCanSendTo() { app, ctx := suite.app, suite.ctx badAddr := sdk.AccAddress([]byte("addr1_______________")) diff --git a/giga/deps/xbank/keeper/send.go b/giga/deps/xbank/keeper/send.go index f4c1b8152a..72bc9ae476 100644 --- a/giga/deps/xbank/keeper/send.go +++ b/giga/deps/xbank/keeper/send.go @@ -2,7 +2,6 @@ package keeper import ( "bytes" - "strings" "github.com/sei-protocol/sei-chain/giga/deps/xbank/types" "github.com/sei-protocol/sei-chain/sei-cosmos/codec" @@ -13,10 +12,6 @@ import ( paramtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/params/types" ) -const ( - TokenFactoryPrefix = "factory" -) - var CoinbaseAddressPrefix = []byte("evm_coinbase") // SendKeeper defines a module interface that facilitates the transfer of coins @@ -38,9 +33,6 @@ type SendKeeper interface { IsSendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error - SetDenomAllowList(ctx sdk.Context, denom string, allowList types.AllowList) - GetDenomAllowList(ctx sdk.Context, denom string) types.AllowList - IsInDenomAllowList(ctx sdk.Context, addr sdk.AccAddress, coins sdk.Coins, cache map[string]AllowedAddresses) bool BlockedAddr(addr sdk.AccAddress) bool RegisterRecipientChecker(RecipientChecker) @@ -452,83 +444,3 @@ func (k BaseSendKeeper) CanSendTo(ctx sdk.Context, recipient sdk.AccAddress) boo func SplitUseiWeiAmount(amt sdk.Int) (sdk.Int, sdk.Int) { return amt.Quo(OneUseiInWei), amt.Mod(OneUseiInWei) } - -func (k BaseSendKeeper) SetDenomAllowList(ctx sdk.Context, denom string, allowList types.AllowList) { - store := k.GetKVStore(ctx) - denomAllowListStore := prefix.NewStore(store, types.DenomAllowListKey(denom)) - - m := k.cdc.MustMarshal(&allowList) - denomAllowListStore.Set([]byte(denom), m) -} - -func (k BaseSendKeeper) GetDenomAllowList(ctx sdk.Context, denom string) types.AllowList { - store := k.GetKVStore(ctx) - store = prefix.NewStore(store, types.DenomAllowListKey(denom)) - - bz := store.Get([]byte(denom)) - if bz == nil { - return types.AllowList{} - } - - var allowList types.AllowList - k.cdc.MustUnmarshal(bz, &allowList) - - return allowList -} - -// IsInDenomAllowList checks if the given address is allowed to send the given coins. -// The check is performed only fot token factory denoms. For each token factory denom, -// it checks if there is allow list for the given denom. If there is no allow list, -// the address is allowed to send the coins. If there is an allow list, the address is -// allowed to send the coins only if it is in the allow list. -func (k BaseSendKeeper) IsInDenomAllowList(ctx sdk.Context, addr sdk.AccAddress, coins sdk.Coins, cache map[string]AllowedAddresses) bool { - for _, coin := range coins { - // Skip if denom does not contain the token factory prefix - if !strings.HasPrefix(coin.Denom, TokenFactoryPrefix) { - continue - } - - allowedAddresses := k.getAllowedAddresses(ctx, cache, coin.Denom) - // skip if there is no allow list for the denom - if len(allowedAddresses.set) == 0 { - continue - } - - if !allowedAddresses.contains(addr) { - return false - } - } - return true -} - -func (k BaseSendKeeper) getAllowedAddresses(ctx sdk.Context, cache map[string]AllowedAddresses, denom string) AllowedAddresses { - allowedAddresses, exists := cache[denom] - if !exists { - allowList := k.GetDenomAllowList(ctx, denom) - allowedAddresses = k.buildAllowedAddressesMap(allowList) - // we cache even if the allowList is empty to avoid multiple db reads - cache[denom] = allowedAddresses - } - return allowedAddresses -} - -type AllowedAddresses struct { - set map[string]struct{} -} - -func (a AllowedAddresses) contains(address sdk.AccAddress) bool { - _, exists := a.set[address.String()] - return exists -} - -func (k BaseSendKeeper) buildAllowedAddressesMap(allowList types.AllowList) AllowedAddresses { - allowedAddressesMap := make(map[string]struct{}) - if len(allowList.Addresses) > 0 { - for _, addr := range allowList.Addresses { - allowedAddressesMap[addr] = struct{}{} - } - } - return AllowedAddresses{ - set: allowedAddressesMap, - } -} diff --git a/giga/deps/xbank/types/bank.pb.go b/giga/deps/xbank/types/bank.pb.go index 3b7955ffe9..52b7b8b61e 100644 --- a/giga/deps/xbank/types/bank.pb.go +++ b/giga/deps/xbank/types/bank.pb.go @@ -418,51 +418,6 @@ func (m *Metadata) GetSymbol() string { return "" } -type AllowList struct { - // Can be empty for no admin, or a valid sei address - Addresses []string `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty" yaml:"addresses"` -} - -func (m *AllowList) Reset() { *m = AllowList{} } -func (m *AllowList) String() string { return proto.CompactTextString(m) } -func (*AllowList) ProtoMessage() {} -func (*AllowList) Descriptor() ([]byte, []int) { - return fileDescriptor_dd052eee12edf988, []int{7} -} -func (m *AllowList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AllowList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_AllowList.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 *AllowList) XXX_Merge(src proto.Message) { - xxx_messageInfo_AllowList.Merge(m, src) -} -func (m *AllowList) XXX_Size() int { - return m.Size() -} -func (m *AllowList) XXX_DiscardUnknown() { - xxx_messageInfo_AllowList.DiscardUnknown(m) -} - -var xxx_messageInfo_AllowList proto.InternalMessageInfo - -func (m *AllowList) GetAddresses() []string { - if m != nil { - return m.Addresses - } - return nil -} - func init() { proto.RegisterType((*Params)(nil), "seiprotocol.sei-chain.gigabank.Params") proto.RegisterType((*SendEnabled)(nil), "seiprotocol.sei-chain.gigabank.SendEnabled") @@ -471,7 +426,6 @@ func init() { proto.RegisterType((*Supply)(nil), "seiprotocol.sei-chain.gigabank.Supply") proto.RegisterType((*DenomUnit)(nil), "seiprotocol.sei-chain.gigabank.DenomUnit") proto.RegisterType((*Metadata)(nil), "seiprotocol.sei-chain.gigabank.Metadata") - proto.RegisterType((*AllowList)(nil), "seiprotocol.sei-chain.gigabank.AllowList") } func init() { proto.RegisterFile("cosmos/bank/v1beta1/bank.proto", fileDescriptor_dd052eee12edf988) } @@ -576,35 +530,6 @@ func (this *Supply) Equal(that interface{}) bool { } return true } -func (this *AllowList) Equal(that interface{}) bool { - if that == nil { - return this == nil - } - - that1, ok := that.(*AllowList) - if !ok { - that2, ok := that.(AllowList) - if ok { - that1 = &that2 - } else { - return false - } - } - if that1 == nil { - return this == nil - } else if this == nil { - return false - } - if len(this.Addresses) != len(that1.Addresses) { - return false - } - for i := range this.Addresses { - if this.Addresses[i] != that1.Addresses[i] { - return false - } - } - return true -} func (m *Params) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -933,38 +858,6 @@ func (m *Metadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *AllowList) 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 *AllowList) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AllowList) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Addresses) > 0 { - for iNdEx := len(m.Addresses) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Addresses[iNdEx]) - copy(dAtA[i:], m.Addresses[iNdEx]) - i = encodeVarintBank(dAtA, i, uint64(len(m.Addresses[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - func encodeVarintBank(dAtA []byte, offset int, v uint64) int { offset -= sovBank(v) base := offset @@ -1120,21 +1013,6 @@ func (m *Metadata) Size() (n int) { return n } -func (m *AllowList) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Addresses) > 0 { - for _, s := range m.Addresses { - l = len(s) - n += 1 + l + sovBank(uint64(l)) - } - } - return n -} - func sovBank(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2040,88 +1918,6 @@ func (m *Metadata) Unmarshal(dAtA []byte) error { } return nil } -func (m *AllowList) 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 ErrIntOverflowBank - } - 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: AllowList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AllowList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Addresses", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowBank - } - 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 ErrInvalidLengthBank - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthBank - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Addresses = append(m.Addresses, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipBank(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthBank - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func skipBank(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/giga/deps/xbank/types/key.go b/giga/deps/xbank/types/key.go index bc55c3bdb8..a4a1def783 100644 --- a/giga/deps/xbank/types/key.go +++ b/giga/deps/xbank/types/key.go @@ -32,7 +32,7 @@ var ( BalancesPrefix = []byte{0x02} SupplyKey = []byte{0x00} DenomMetadataPrefix = []byte{0x1} - DenomAllowListPrefix = []byte{0x11} + DenomAllowListPrefix = []byte{0x11} // deprecated ) // DenomMetadataKey returns the denomination metadata key. @@ -41,12 +41,6 @@ func DenomMetadataKey(denom string) []byte { return append(DenomMetadataPrefix, d...) } -// DenomAllowListKey returns the denomination allow list key. -func DenomAllowListKey(denom string) []byte { - d := []byte(denom) - return append(DenomAllowListPrefix, d...) -} - // AddressFromBalancesStore returns an account address from a balances prefix // store. The key must not contain the prefix BalancesPrefix as the prefix store // iterator discards the actual prefix. diff --git a/integration_test/authz_module/generic_authorization_test.yaml b/integration_test/authz_module/generic_authorization_test.yaml index 9ebf3737dc..4ead0c817f 100644 --- a/integration_test/authz_module/generic_authorization_test.yaml +++ b/integration_test/authz_module/generic_authorization_test.yaml @@ -3,29 +3,28 @@ # Get admin addr - cmd: printf "12345678\n" | seid keys list --output json | jq ".[] | select (.name==\"admin\")" | jq -r .address env: ADMIN_ADDR - # MSG type "/seiprotocol.seichain.tokenfactory.MsgCreateDenom" - # create new grantee addr - - cmd: printf "12345678\ny\n" | seid keys add grantee --output json | jq -r ".address" + # create a grantee of its own, so this generic grant does not replace the send authorization test's grant + - cmd: printf "12345678\ny\n" | seid keys add generic-grantee --output json | jq -r ".address" env: GRANTEE_ADDR + # create the recipient of the send the grantee executes + - cmd: printf "12345678\ny\n" | seid keys add generic-recipient --output json | jq -r ".address" + env: RECIPIENT_ADDR # send some funds to grantee for gas - cmd: seidbin=seid; chainid=sei; source integration_test/utils/_tx_helpers.sh && submit_tx_and_wait admin bank send admin $GRANTEE_ADDR 1sei --fees 2000usei - # create an authz grant for tokenfactory create denom - - cmd: seidbin=seid; chainid=sei; source integration_test/utils/_tx_helpers.sh && submit_tx_and_wait admin authz grant $GRANTEE_ADDR generic --msg-type "/seiprotocol.seichain.tokenfactory.MsgCreateDenom" --fees 2000usei - - cmd: uuidgen - env: TF_UUID - # create TF create-denom tx and write to json - - cmd: printf "12345678\n" | seid tx tokenfactory create-denom $TF_UUID --from $ADMIN_ADDR --generate-only > create_denom_tx.json + # create a generic authz grant for bank send + - cmd: seidbin=seid; chainid=sei; source integration_test/utils/_tx_helpers.sh && submit_tx_and_wait admin authz grant $GRANTEE_ADDR generic --msg-type "/cosmos.bank.v1beta1.MsgSend" --fees 2000usei + # generate a bank send from admin and write it to json + - cmd: printf "12345678\n" | seid tx bank send $ADMIN_ADDR $RECIPIENT_ADDR 3sei --generate-only > generic_send_tx.json # execute the authz tx - we want to validate that this succeeds with code 0 - - cmd: seidbin=seid; chainid=sei; source integration_test/utils/_tx_helpers.sh && submit_tx_and_wait $GRANTEE_ADDR authz exec create_denom_tx.json --fees 2000usei + - cmd: seidbin=seid; chainid=sei; source integration_test/utils/_tx_helpers.sh && submit_tx_and_wait $GRANTEE_ADDR authz exec generic_send_tx.json --fees 2000usei env: AUTHZ_1_ERROR_CODE - # verify that the denom exists - - cmd: seid q tokenfactory denom-authority-metadata factory/$ADMIN_ADDR/$TF_UUID --output json | jq -r ".authority_metadata.admin" - env: TF_ADMIN - # verify that the admin is ADMIN_ADDR + # query the recipient's balance to validate the send was executed on admin's behalf + - cmd: seid q bank balances $RECIPIENT_ADDR --denom usei --output json | jq -r ".amount" + env: RECIPIENT_BALANCE verifiers: - # verify that error code == 0 for first authz exec + # verify that error code == 0 for the authz exec - type: eval expr: AUTHZ_1_ERROR_CODE == 0 - # verify TF metadata is correct + # verify that the recipient holds the 3 sei the grantee sent - type: eval - expr: TF_ADMIN == ADMIN_ADDR \ No newline at end of file + expr: RECIPIENT_BALANCE == 3000000 diff --git a/integration_test/contracts/create_tokenfactory_denoms.sh b/integration_test/contracts/create_tokenfactory_denoms.sh deleted file mode 100755 index dc036224be..0000000000 --- a/integration_test/contracts/create_tokenfactory_denoms.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/bash - -seidbin=$(which ~/go/bin/seid | tr -d '"') -keyname=admin -keyaddress=$(printf "12345678\n" | $seidbin keys show "$keyname" -a 2>/dev/null) -chainid=$($seidbin status | jq ".NodeInfo.network" | tr -d '"') -seihome=$(git rev-parse --show-toplevel | tr -d '"') - -source "$(dirname "$0")/../utils/_tx_helpers.sh" - -cd $seihome || exit -echo "Deploying first set of tokenfactory denoms..." - -# Capture a committed baseline height before the first denom creation. This -# script later records and compares state around "beginning block height", so -# under allow_empty_blocks=false we must force one real block and remember the -# exact inclusion height instead of sampling status at height 0 / an idle tip. -bootstrap_block_height=$(bank_send_and_get_height "$keyname" "$keyaddress" "1usei") || exit 1 -beginning_block_height="$bootstrap_block_height" -echo "$beginning_block_height" > $seihome/integration_test/contracts/tfk_beginning_block_height.txt -echo "$keyaddress" > $seihome/integration_test/contracts/tfk_creator_id.txt - -# Create a tokenfactory denom and wait for it to appear on chain. The -# denom is deterministic: factory//. Submitted via -# -b sync (the cosmos KV indexer isn't fed under Autobahn, so -b block -# hangs); poll denom-authority-metadata for non-empty admin as the -# side-effect signal that DeliverTx committed. -create_denom_and_wait() { - local subdenom="$1" - local new_token_denom="factory/$keyaddress/$subdenom" - local resp; resp=$(printf "12345678\n" | $seidbin tx tokenfactory create-denom "$subdenom" \ - -y --from="$keyname" --chain-id="$chainid" --gas=500000 --fees=100000usei \ - --broadcast-mode=sync --output=json) - local code; code=$(echo "$resp" | jq -r '.code // 0') - if [ "$code" != "0" ]; then - echo "create_denom_and_wait CheckTx rejected: $(echo "$resp" | jq -r '.raw_log')" >&2 - return 1 - fi - # denom-authority-metadata returns {"authority_metadata":{"admin":""}} - # (no error) for a non-existent denom; only a non-empty admin - # indicates create-denom is committed. - _wait_until "tokenfactory denom $new_token_denom" " - admin=\$($seidbin q tokenfactory denom-authority-metadata $new_token_denom -o json 2>/dev/null | jq -r '.authority_metadata.admin // \"\"') - [ -n \"\$admin\" ] - " || return 1 - echo "$new_token_denom" -} - -# create first set of tokenfactory denoms -for i in {1..10} -do - echo "Creating first set of tokenfactory denoms #$i..." - new_token_denom=$(create_denom_and_wait "$i") || exit 1 - echo "Got token $new_token_denom for iteration $i" -done - - -first_set_block_height=$($seidbin status | jq -r '.SyncInfo.latest_block_height') -echo "$first_set_block_height" > $seihome/integration_test/contracts/tfk_first_set_block_height.txt - -sleep 5 - -# create second set of tokenfactory denoms -for i in {11..20} -do - echo "Creating first set of tokenfactory denoms #$i..." - new_token_denom=$(create_denom_and_wait "$i") || exit 1 - echo "Got token $new_token_denom for iteration $i" -done - -second_set_block_height=$($seidbin status | jq -r '.SyncInfo.latest_block_height') -echo "$second_set_block_height" > $seihome/integration_test/contracts/tfk_second_set_block_height.txt - -sleep 5 - -# create third set of tokenfactory denoms -for i in {21..30} -do - echo "Creating first set of tokenfactory denoms #$i..." - new_token_denom=$(create_denom_and_wait "$i") || exit 1 - echo "Got token $new_token_denom for iteration $i" -done - -third_set_block_height=$($seidbin status | jq -r '.SyncInfo.latest_block_height') -echo "$third_set_block_height" > $seihome/integration_test/contracts/tfk_third_set_block_height.txt - -num_denoms=$(seid q tokenfactory denoms-from-creator $CREATOR_ID --output json | jq -r ".denoms | length") -echo $num_denoms - -exit 0 diff --git a/integration_test/dapp_tests/utils.js b/integration_test/dapp_tests/utils.js index 24fa231d61..1ea5dcc8ad 100644 --- a/integration_test/dapp_tests/utils.js +++ b/integration_test/dapp_tests/utils.js @@ -70,13 +70,6 @@ async function deployEthersContract(name, abi, bytecode, deployer, deployParams= return deployed; } -async function doesTokenFactoryDenomExist(denom) { - const output = await execute(`seid q tokenfactory denom-authority-metadata ${denom} --output json`); - const parsed = JSON.parse(output); - - return parsed.authority_metadata.admin !== ""; -} - async function sendFunds(amountSei, recipient, signer) { const bal = await signer.getBalance(); @@ -331,7 +324,6 @@ module.exports = { deployTokenPool, supplyLiquidity, deployEthersContract, - doesTokenFactoryDenomExist, pollBalance, sendFunds }; \ No newline at end of file diff --git a/integration_test/precompile_tests/precompiles/bank.spec.ts b/integration_test/precompile_tests/precompiles/bank.spec.ts index 09cf906703..484de3b785 100644 --- a/integration_test/precompile_tests/precompiles/bank.spec.ts +++ b/integration_test/precompile_tests/precompiles/bank.spec.ts @@ -14,8 +14,9 @@ import { EvmAccount, associateViaTx } from '../utils/evmUtils'; import { bankBalance, bankSupplyOf, + cosmosQuery, + denomWithMetadata, generateSeiAddress, - createTokenfactoryDenom, } from '../utils/cosmosUtils'; import { bankParams } from '../utils/moduleQueries'; import { @@ -39,7 +40,7 @@ describe('bank precompile (0x1001)', function () { let admin: EvmAccount; let bank: ethers.Contract; let caller: ethers.Contract; - /** Tokenfactory denom minted by the denomMetadata test, reused by denomsMetadata. */ + /** Denom whose metadata the denomMetadata test checked, reused by denomsMetadata. */ let metadataDenom = ''; before(() => { @@ -170,9 +171,9 @@ describe('bank precompile (0x1001)', function () { const before: bigint = await bank.supply('usei'); // totalSupply sends no page limit, so the bank module's default of - // 100 applies. Supply is keyed by denom and every factory/… denom - // this suite mints sorts before usei, so on a long-lived devnet usei - // is not on page one and only walking the pages finds it. + // 100 applies. Supply is keyed by denom, so on a devnet holding more + // than a page of denoms that sort before usei, only walking the pages + // finds it. let pageKey: Uint8Array = new Uint8Array(); let usei: { amount: bigint; denom: string } | undefined; for (let page = 0; page < 50 && usei === undefined; page++) { @@ -207,22 +208,25 @@ describe('bank precompile (0x1001)', function () { expect(viaPrecompile.defaultSendEnabled).to.equal(true); }); - it('denomMetadata returns tokenfactory metadata for a created denom', async () => { - // Fresh devnets may not register usei metadata (see name/symbol above); - // tokenfactory always writes name/symbol/base/display = the full denom - // and a single exponent-0 unit, which is the fixture this query needs. - metadataDenom = await createTokenfactoryDenom( - runtime.funded.adminMnemonic, - `bnk${Date.now().toString(36)}`, + it('denomMetadata matches the bank module for a denom carrying metadata', async () => { + // Fresh devnets may not register usei metadata (see name/symbol above), + // so the fixture is a denom the bank module does hold metadata for. + metadataDenom = await denomWithMetadata(); + const qc = await cosmosQuery(); + const [meta, want] = await Promise.all([ + bank.denomMetadata(metadataDenom), + qc.bank.denomMetadata(metadataDenom), + ]); + expect(meta.base).to.equal(want.base); + expect(meta.name).to.equal(want.name); + expect(meta.symbol).to.equal(want.symbol); + expect(meta.display).to.equal(want.display); + expect(meta.denomUnits.length, 'precompile vs bank module denom units').to.equal( + want.denomUnits.length, ); - const meta = await bank.denomMetadata(metadataDenom); - expect(meta.base).to.equal(metadataDenom); - expect(meta.name).to.equal(metadataDenom); - expect(meta.symbol).to.equal(metadataDenom); - expect(meta.display).to.equal(metadataDenom); - expect(meta.denomUnits.length, 'tokenfactory writes one denom unit').to.be.greaterThan(0); - expect(meta.denomUnits[0].denom).to.equal(metadataDenom); - expect(Number(meta.denomUnits[0].exponent)).to.equal(0); + expect(meta.denomUnits.length, 'metadata carries at least one denom unit').to.be.greaterThan(0); + expect(meta.denomUnits[0].denom).to.equal(want.denomUnits[0].denom); + expect(Number(meta.denomUnits[0].exponent)).to.equal(want.denomUnits[0].exponent); }); it('denomsMetadata pages until it reaches the denom denomMetadata just returned', async () => { diff --git a/integration_test/precompile_tests/precompiles/pointer.spec.ts b/integration_test/precompile_tests/precompiles/pointer.spec.ts index c6af462611..4dc61e65e5 100644 --- a/integration_test/precompile_tests/precompiles/pointer.spec.ts +++ b/integration_test/precompile_tests/precompiles/pointer.spec.ts @@ -5,16 +5,15 @@ * selectors still decode and revert; at an unregistered address the same call would * succeed against empty code and return no data. * - * Fixture: a tokenfactory denom created from the admin's cosmos key — x/tokenfactory - * sets bank denom metadata automatically on creation, which is what the creation path - * used to require. A refusal here is therefore the retirement rather than the - * missing-metadata rejection that preceded it. + * Fixture: a denom carrying bank metadata, read from the bank module — bank metadata + * is what the creation path used to require. A refusal here is therefore the + * retirement rather than the missing-metadata rejection that preceded it. */ import { ethers } from 'ethers'; import { expect } from 'chai'; import { seiRpc } from '../utils/chainUtils'; import { EvmAccount } from '../utils/evmUtils'; -import { createTokenfactoryDenom } from '../utils/cosmosUtils'; +import { denomWithMetadata } from '../utils/cosmosUtils'; import { PRECOMPILE_ADDRESSES, precompileContract, @@ -46,11 +45,7 @@ describe('pointer precompile (0x100b)', function () { pointer = precompileContract('pointer', admin.wallet); pointerview = precompileContract('pointerview', provider); caller = callerContract(runtime, admin.wallet); - // Unique subdenom so reruns against a long-lived devnet never collide. - denom = await createTokenfactoryDenom( - runtime.funded.adminMnemonic, - `ptr${Date.now().toString(36)}`, - ); + denom = await denomWithMetadata(); }); describe('creation is refused', () => { diff --git a/integration_test/precompile_tests/utils/cosmosUtils.ts b/integration_test/precompile_tests/utils/cosmosUtils.ts index 71d0492270..a81914362b 100644 --- a/integration_test/precompile_tests/utils/cosmosUtils.ts +++ b/integration_test/precompile_tests/utils/cosmosUtils.ts @@ -12,7 +12,6 @@ import { DistributionExtension, SigningStargateClient, defaultRegistryTypes, - assertIsDeliverTxSuccess, } from '@cosmjs/stargate'; import { Tendermint34Client } from '@cosmjs/tendermint-rpc'; import { DirectSecp256k1HdWallet, Registry } from '@cosmjs/proto-signing'; @@ -132,43 +131,17 @@ export async function bankSupplyOf(denom = 'usei'): Promise { } /** - * Create a tokenfactory denom from `mnemonic` and wait until its bank metadata - * is visible. x/tokenfactory sets denom metadata automatically on creation - * (name/symbol = the full `factory//` string, exponent 0). - * Returns the full denom. + * The base of the first denom the bank module holds metadata for. Nothing on chain + * creates denom metadata at runtime, so this is genesis state: the docker devnet + * seeds metadata for `uatom`. */ -export async function createTokenfactoryDenom( - mnemonic: string, - subdenom: string, -): Promise { - const wallet = await seiWalletFromMnemonic(mnemonic); - const [account] = await wallet.getAccounts(); - const registry = new Registry([...seiProtoRegistry, ...defaultRegistryTypes]); - const client = await SigningStargateClient.connectWithSigner(Endpoints.sei.cosmosRpc, wallet, { - registry, - }); - try { - const msg = { - typeUrl: `/${Encoder.tokenfactory.MsgCreateDenom.$type}`, - value: Encoder.tokenfactory.MsgCreateDenom.fromPartial({ - sender: account.address, - subdenom, - }), - }; - const fee = { amount: coins(40000, 'usei'), gas: '400000' }; - const res = await client.signAndBroadcast(account.address, [msg], fee, 'create denom'); - assertIsDeliverTxSuccess(res); - } finally { - client.disconnect(); - } - - const denom = `factory/${account.address}/${subdenom}`; +export async function denomWithMetadata(): Promise { const qc = await cosmosQuery(); - await waitUntil(async () => (await qc.bank.denomMetadata(denom)) ?? null, { - timeoutMs: 30_000, - label: `bank metadata for ${denom}`, - }); - return denom; + const [metadata] = await qc.bank.denomsMetadata(); + if (!metadata) { + throw new Error('denomWithMetadata: the bank module holds metadata for no denom'); + } + return metadata.base; } /** True when a local `sei-node-0` docker container is running. */ diff --git a/integration_test/runner/runner_test.go b/integration_test/runner/runner_test.go index 3b8c6242ad..36a2c5f149 100644 --- a/integration_test/runner/runner_test.go +++ b/integration_test/runner/runner_test.go @@ -59,10 +59,6 @@ func TestDistributionModule(t *testing.T) { runner.RunFile(t, "../distribution_module/rewards.yaml") } -func TestTokenFactoryModule(t *testing.T) { - runner.RunFile(t, "../tokenfactory_module/create_tokenfactory_test.yaml") -} - func TestAuthzModule(t *testing.T) { runner.RunFile(t, "../authz_module/send_authorization_test.yaml") runner.RunFile(t, "../authz_module/staking_authorization_test.yaml") @@ -91,7 +87,7 @@ func TestSeiDBFlatKV(t *testing.T) { } // TestSeiDBStateStore runs state-store iteration tests. -// In CI wasm contracts and tokenfactory denoms are deployed as a prerequisite. +// In CI wasm contracts are deployed as a prerequisite. func TestSeiDBStateStore(t *testing.T) { runner.RunFile(t, "../seidb/state_store_test.yaml") } diff --git a/integration_test/seidb/state_store_test.yaml b/integration_test/seidb/state_store_test.yaml index ed89dd3c90..3ca7a63e0b 100644 --- a/integration_test/seidb/state_store_test.yaml +++ b/integration_test/seidb/state_store_test.yaml @@ -90,43 +90,3 @@ expr: FIRST_ID_FIRST_SET == 4 - type: eval expr: SECOND_ID_FIRST_SET == 17 - -- name: Test state store iteration through tokenfactory denoms - inputs: - # Get creator id - - cmd: tail -1 integration_test/contracts/tfk_creator_id.txt - env: CREATOR_ID - # Get height from beginning - - cmd: tail -1 integration_test/contracts/tfk_beginning_block_height.txt - env: BEGINNING_BLOCK_HEIGHT - # Verify 0 tfk denoms created at beginning - - cmd: seid q tokenfactory denoms-from-creator $CREATOR_ID --height $BEGINNING_BLOCK_HEIGHT --output json | jq -r ".denoms | length" - env: BEGINNING_TFK_DENOMS - # Get height from first set - - cmd: tail -1 integration_test/contracts/tfk_first_set_block_height.txt - env: FIRST_SET_BLOCK_HEIGHT - # Verify 100 tfk denoms created at first - - cmd: seid q tokenfactory denoms-from-creator $CREATOR_ID --height $FIRST_SET_BLOCK_HEIGHT --output json | jq -r ".denoms | length" - env: FIRST_SET_TFK_DENOMS - # Get height from second set - - cmd: tail -1 integration_test/contracts/tfk_second_set_block_height.txt - env: SECOND_SET_BLOCK_HEIGHT - # Verify 200 tfk denoms created at second set - - cmd: seid q tokenfactory denoms-from-creator $CREATOR_ID --height $SECOND_SET_BLOCK_HEIGHT --output json | jq -r ".denoms | length" - env: SECOND_SET_TFK_DENOMS - # Get height from third set - - cmd: tail -1 integration_test/contracts/tfk_third_set_block_height.txt - env: THIRD_SET_BLOCK_HEIGHT - # Verify 300 tfk denoms created at third set - - cmd: seid q tokenfactory denoms-from-creator $CREATOR_ID --height $THIRD_SET_BLOCK_HEIGHT --output json | jq -r ".denoms | length" - env: THIRD_SET_TFK_DENOMS - verifiers: - # Verify number of wasm codes at each height - - type: eval - expr: BEGINNING_TFK_DENOMS == 0 - - type: eval - expr: FIRST_SET_TFK_DENOMS == 10 - - type: eval - expr: SECOND_SET_TFK_DENOMS == 20 - - type: eval - expr: THIRD_SET_TFK_DENOMS == 30 diff --git a/integration_test/tokenfactory_module/create_tokenfactory_test.yaml b/integration_test/tokenfactory_module/create_tokenfactory_test.yaml deleted file mode 100644 index 3b042e4ee8..0000000000 --- a/integration_test/tokenfactory_module/create_tokenfactory_test.yaml +++ /dev/null @@ -1,51 +0,0 @@ -- name: Test creating a denom - inputs: - # Get admin - - cmd: printf "12345678\n" | seid keys list --output json | jq ".[] | select (.name==\"admin\")" | jq -r .address - env: ADMIN_ADDR - # create new admin addr - - cmd: printf "12345678\ny\n" | seid keys add new_admin_addr --output json | jq -r ".address" - env: NEW_ADMIN_ADDR - # create uuid for tokenfactory denom - - cmd: uuidgen - env: TKF_UUID - # Create denom - - cmd: printf "12345678\n" | seid tx tokenfactory create-denom $TKF_UUID --from admin --fees 2000usei -y -b block - # Query various fields about denom - - cmd: seid q bank denom-metadata --output json | jq .metadatas | jq ".[] | select (.base==\"factory/${ADMIN_ADDR}/${TKF_UUID}\")" | jq -r .base - env: BASE - - cmd: seid q bank denom-metadata --output json | jq .metadatas | jq ".[] | select (.base==\"factory/${ADMIN_ADDR}/${TKF_UUID}\")" | jq -r .name - env: NAME - - cmd: seid q bank denom-metadata --output json | jq .metadatas | jq ".[] | select (.base==\"factory/${ADMIN_ADDR}/${TKF_UUID}\")" | jq -r .symbol - env: SYMBOL - - cmd: seid q bank denom-metadata --output json | jq .metadatas | jq ".[] | select (.base==\"factory/${ADMIN_ADDR}/${TKF_UUID}\")" | jq -r .display - env: DISPLAY - # mint some token - - cmd: printf "12345678\n" | seid tx tokenfactory mint 100$NAME --from admin -b block -y --fees 2000usei - # query balance - - cmd: seid q bank balances $ADMIN_ADDR --denom $NAME --output json | jq -r ".amount" - env: MINTED_BALANCE - # burn some token - - cmd: printf "12345678\n" | seid tx tokenfactory burn 60$NAME --from admin -b block -y --fees 2000usei - # query balance after burn - - cmd: seid q bank balances $ADMIN_ADDR --denom $NAME --output json | jq -r ".amount" - env: BALANCE_AFTER_BURN - # change admin - - cmd: printf "12345678\n" | seid tx tokenfactory change-admin $NAME $NEW_ADMIN_ADDR --from admin -b block -y --fees 2000usei - # query balance after burn - - cmd: seid q tokenfactory denom-authority-metadata $NAME --output json | jq -r ".authority_metadata.admin" - env: NEW_ADMIN - verifiers: - # All fields should be populated and match the base name - - type: eval - expr: NAME == BASE and SYMBOL == BASE and DISPLAY == BASE - # verify minted balance - - type: eval - expr: MINTED_BALANCE == 100 - # verify balance after burn - - type: eval - expr: BALANCE_AFTER_BURN == 40 - # verify new admin addr - - type: eval - expr: NEW_ADMIN_ADDR == NEW_ADMIN - diff --git a/loadtest/loadtest_client.go b/loadtest/loadtest_client.go index b82558bbe2..3d65363a80 100644 --- a/loadtest/loadtest_client.go +++ b/loadtest/loadtest_client.go @@ -42,8 +42,6 @@ type LoadTestClient struct { Validators []stakingtypes.Validator // DelegationMap is a map of delegator -> validator -> delegated amount DelegationMap map[string]map[string]int - // Tokenfactory specific variables - TokenFactoryDenomOwner map[string]string // Only one admin message can go in per block generatedAdminMessageForBlock bool // Messages that has to be sent from the admin account @@ -80,7 +78,6 @@ func NewLoadTestClient(config Config) *LoadTestClient { GrpcConns: grpcConns, StakingQueryClient: stakingtypes.NewQueryClient(grpcConns[0]), DelegationMap: map[string]map[string]int{}, - TokenFactoryDenomOwner: map[string]string{}, generatedAdminMessageForBlock: false, isAdminMessageMapping: map[string]bool{CollectRewards: true, DistributeRewards: true}, mtx: &sync.RWMutex{}, diff --git a/loadtest/main.go b/loadtest/main.go index df0c80869f..0da3b356d6 100644 --- a/loadtest/main.go +++ b/loadtest/main.go @@ -39,7 +39,6 @@ import ( "golang.org/x/time/rate" "github.com/sei-protocol/sei-chain/app" - tokenfactorytypes "github.com/sei-protocol/sei-chain/x/tokenfactory/types" "go.opentelemetry.io/otel/attribute" otelmetric "go.opentelemetry.io/otel/metric" ) @@ -413,31 +412,6 @@ func (c *LoadTestClient) generateMessage(key cryptotypes.PrivKey, msgType string } c.mtx.RUnlock() msgs = []sdk.Msg{c.generateStakingMsg(delegatorAddr, chosenValidator, srcAddr)} - case Tokenfactory: - denomCreatorAddr := sdk.AccAddress(key.PubKey().Address()).String() - // No denoms, let's mint - randNum := r.Float64() - denom, ok := c.TokenFactoryDenomOwner[denomCreatorAddr] - switch { - case !ok || randNum <= 0.33: - subDenom := fmt.Sprintf("tokenfactory-created-denom-%d", time.Now().UnixMilli()) - denom = fmt.Sprintf("factory/%s/%s", denomCreatorAddr, subDenom) - msgs = []sdk.Msg{&tokenfactorytypes.MsgCreateDenom{ - Sender: denomCreatorAddr, - Subdenom: subDenom, - }} - c.TokenFactoryDenomOwner[denomCreatorAddr] = denom - case randNum <= 0.66: - msgs = []sdk.Msg{&tokenfactorytypes.MsgMint{ - Sender: denomCreatorAddr, - Amount: sdk.Coin{Denom: denom, Amount: sdk.NewInt(10)}, - }} - default: - msgs = []sdk.Msg{&tokenfactorytypes.MsgBurn{ - Sender: denomCreatorAddr, - Amount: sdk.Coin{Denom: denom, Amount: sdk.NewInt(1)}, - }} - } case FailureBankMalformed: var denom string if r.Float64() < 0.5 { diff --git a/loadtest/types.go b/loadtest/types.go index ce8a678b3c..c40451b189 100644 --- a/loadtest/types.go +++ b/loadtest/types.go @@ -28,7 +28,6 @@ const ( FailureDexInvalid string = "failure_dex_invalid" Dex string = "dex" Staking string = "staking" - Tokenfactory string = "tokenfactory" Limit string = "limit" Market string = "market" WasmMintNft string = "wasm_mint_nft" diff --git a/proto/tokenfactory/authority_metadata.proto b/proto/tokenfactory/authority_metadata.proto deleted file mode 100644 index 0e1cfa9b8f..0000000000 --- a/proto/tokenfactory/authority_metadata.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; -package seiprotocol.seichain.tokenfactory; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/sei-protocol/sei-chain/x/tokenfactory/types"; - -// 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. -message DenomAuthorityMetadata { - option (gogoproto.equal) = true; - - // Can be empty for no admin, or a valid sei address - string admin = 1 [(gogoproto.moretags) = "yaml:\"admin\""]; -} diff --git a/proto/tokenfactory/genesis.proto b/proto/tokenfactory/genesis.proto deleted file mode 100644 index c9511f191d..0000000000 --- a/proto/tokenfactory/genesis.proto +++ /dev/null @@ -1,32 +0,0 @@ -syntax = "proto3"; -package seiprotocol.seichain.tokenfactory; - -import "gogoproto/gogo.proto"; -import "tokenfactory/authority_metadata.proto"; -import "tokenfactory/params.proto"; - -option go_package = "github.com/sei-protocol/sei-chain/x/tokenfactory/types"; - -// GenesisState defines the tokenfactory module's genesis state. -message GenesisState { - // params defines the paramaters of the module. - Params params = 1 [(gogoproto.nullable) = false]; - - repeated GenesisDenom factory_denoms = 2 [ - (gogoproto.moretags) = "yaml:\"factory_denoms\"", - (gogoproto.nullable) = false - ]; -} - -// GenesisDenom defines a tokenfactory denom that is defined within genesis -// state. The structure contains DenomAuthorityMetadata which defines the -// denom's admin. -message GenesisDenom { - option (gogoproto.equal) = true; - - string denom = 1 [(gogoproto.moretags) = "yaml:\"denom\""]; - DenomAuthorityMetadata authority_metadata = 2 [ - (gogoproto.moretags) = "yaml:\"authority_metadata\"", - (gogoproto.nullable) = false - ]; -} diff --git a/proto/tokenfactory/params.proto b/proto/tokenfactory/params.proto deleted file mode 100644 index af4efddd80..0000000000 --- a/proto/tokenfactory/params.proto +++ /dev/null @@ -1,9 +0,0 @@ -syntax = "proto3"; -package seiprotocol.seichain.tokenfactory; - -option go_package = "github.com/sei-protocol/sei-chain/x/tokenfactory/types"; - -// Params defines the parameters for the tokenfactory module. -message Params { - uint32 denom_allowlist_max_size = 1; -} diff --git a/proto/tokenfactory/query.proto b/proto/tokenfactory/query.proto deleted file mode 100644 index 566571bb86..0000000000 --- a/proto/tokenfactory/query.proto +++ /dev/null @@ -1,107 +0,0 @@ -syntax = "proto3"; -package seiprotocol.seichain.tokenfactory; - -import "cosmos/bank/v1beta1/bank.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "tokenfactory/authority_metadata.proto"; -import "tokenfactory/params.proto"; - -option go_package = "github.com/sei-protocol/sei-chain/x/tokenfactory/types"; - -// Query defines the gRPC querier service. -service Query { - // Params defines a gRPC query method that returns the tokenfactory module's - // parameters. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/sei-protocol/seichain/tokenfactory/params"; - } - - // DenomAuthorityMetadata defines a gRPC query method for fetching - // DenomAuthorityMetadata for a particular denom. - rpc DenomAuthorityMetadata(QueryDenomAuthorityMetadataRequest) returns (QueryDenomAuthorityMetadataResponse) { - option (google.api.http).get = "/sei-protocol/seichain/tokenfactory/denoms/{denom}/authority_metadata"; - } - - // DenomsMetadata defines a gRPC query method for fetching - // DenomMetadata for a particular denom. - rpc DenomMetadata(QueryDenomMetadataRequest) returns (QueryDenomMetadataResponse) { - option (google.api.http).get = "/sei-protocol/seichain/tokenfactory/denoms/metadata"; - } - - // DenomsFromCreator defines a gRPC query method for fetching all - // denominations created by a specific admin/creator. - rpc DenomsFromCreator(QueryDenomsFromCreatorRequest) returns (QueryDenomsFromCreatorResponse) { - option (google.api.http).get = "/sei-protocol/seichain/tokenfactory/denoms_from_creator/{creator}"; - } - - // DenomAllowList defines a gRPC query method for fetching the denom allow list - rpc DenomAllowList(QueryDenomAllowListRequest) returns (QueryDenomAllowListResponse) { - option (google.api.http).get = "/sei-protocol/seichain/tokenfactory/denoms/allow_list"; - } -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1 [(gogoproto.nullable) = false]; -} - -// QueryDenomAuthorityMetadataRequest defines the request structure for the -// DenomAuthorityMetadata gRPC query. -message QueryDenomAuthorityMetadataRequest { - string denom = 1 [(gogoproto.moretags) = "yaml:\"denom\""]; -} - -// QueryDenomAuthorityMetadataResponse defines the response structure for the -// DenomAuthorityMetadata gRPC query. -message QueryDenomAuthorityMetadataResponse { - DenomAuthorityMetadata authority_metadata = 1 [ - (gogoproto.moretags) = "yaml:\"authority_metadata\"", - (gogoproto.nullable) = false - ]; -} - -// QueryDenomsFromCreatorRequest defines the request structure for the -// DenomsFromCreator gRPC query. -message QueryDenomsFromCreatorRequest { - string creator = 1 [(gogoproto.moretags) = "yaml:\"creator\""]; - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryDenomsFromCreatorResponse defines the response structure for the -// DenomsFromCreator gRPC query. -message QueryDenomsFromCreatorResponse { - repeated string denoms = 1 [(gogoproto.moretags) = "yaml:\"denoms\""]; - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryDenomMetadataRequest is the request type for the DenomMetadata gRPC method. -message QueryDenomMetadataRequest { - // denom is the coin denom to query the metadata for. - string denom = 1; -} - -// QueryDenomMetadataResponse is the response type for the Query/DenomMetadata gRPC -// method. -message QueryDenomMetadataResponse { - // metadata describes and provides all the client information for the requested token. - cosmos.bank.v1beta1.Metadata metadata = 1 [(gogoproto.nullable) = false]; -} - -// QueryDenomAllowListRequest is the request type for the DenomAllowList gRPC method -message QueryDenomAllowListRequest { - // denom is the coin denom to query the allowlist for. - string denom = 1; -} - -// QueryDenomAllowListResponse is the response type for the DenomAllowList gRPC -// method. -message QueryDenomAllowListResponse { - // allow_list provides addresses allowed for the requested token. - cosmos.bank.v1beta1.AllowList allow_list = 1 [(gogoproto.nullable) = false]; -} diff --git a/proto/tokenfactory/tx.proto b/proto/tokenfactory/tx.proto deleted file mode 100644 index 804e888ed6..0000000000 --- a/proto/tokenfactory/tx.proto +++ /dev/null @@ -1,106 +0,0 @@ -syntax = "proto3"; -package seiprotocol.seichain.tokenfactory; - -import "cosmos/bank/v1beta1/bank.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "gogoproto/gogo.proto"; - -option go_package = "github.com/sei-protocol/sei-chain/x/tokenfactory/types"; - -// Msg defines the tokefactory module's gRPC message service. -service Msg { - rpc CreateDenom(MsgCreateDenom) returns (MsgCreateDenomResponse); - rpc UpdateDenom(MsgUpdateDenom) returns (MsgUpdateDenomResponse); - rpc Mint(MsgMint) returns (MsgMintResponse); - rpc Burn(MsgBurn) returns (MsgBurnResponse); - rpc ChangeAdmin(MsgChangeAdmin) returns (MsgChangeAdminResponse); - rpc SetDenomMetadata(MsgSetDenomMetadata) returns (MsgSetDenomMetadataResponse); -} - -// MsgCreateDenom defines the message structure for the CreateDenom gRPC service -// method. It allows an account to create a new denom. It requires a sender -// address and a sub denomination. The (sender_address, sub_denomination) tuple -// must be unique and cannot be re-used. -// -// The resulting denom created is defined as -// . The resulting denom's admin is -// originally set to be the creator, but this can be changed later. The token -// denom does not indicate the current admin. -message MsgCreateDenom { - string sender = 1 [(gogoproto.moretags) = "yaml:\"sender\""]; - // subdenom can be up to 44 "alphanumeric" characters long. - string subdenom = 2 [(gogoproto.moretags) = "yaml:\"subdenom\""]; - cosmos.bank.v1beta1.AllowList allow_list = 3 [ - (gogoproto.moretags) = "yaml:\"allow_list\"", - (gogoproto.nullable) = true - ]; -} - -// MsgCreateDenomResponse is the return value of MsgCreateDenom -// It returns the full string of the newly created denom -message MsgCreateDenomResponse { - string new_token_denom = 1 [(gogoproto.moretags) = "yaml:\"new_token_denom\""]; -} - -// MsgMint is the sdk.Msg type for allowing an admin account to mint -// more of a token. For now, we only support minting to the sender account -message MsgMint { - string sender = 1 [(gogoproto.moretags) = "yaml:\"sender\""]; - cosmos.base.v1beta1.Coin amount = 2 [ - (gogoproto.moretags) = "yaml:\"amount\"", - (gogoproto.nullable) = false - ]; -} - -message MsgMintResponse {} - -// MsgBurn is the sdk.Msg type for allowing an admin account to burn -// a token. For now, we only support burning from the sender account. -message MsgBurn { - string sender = 1 [(gogoproto.moretags) = "yaml:\"sender\""]; - cosmos.base.v1beta1.Coin amount = 2 [ - (gogoproto.moretags) = "yaml:\"amount\"", - (gogoproto.nullable) = false - ]; -} - -message MsgBurnResponse {} - -// MsgChangeAdmin is the sdk.Msg type for allowing an admin account to reassign -// adminship of a denom to a new account -message MsgChangeAdmin { - string sender = 1 [(gogoproto.moretags) = "yaml:\"sender\""]; - string denom = 2 [(gogoproto.moretags) = "yaml:\"denom\""]; - string new_admin = 3 [(gogoproto.moretags) = "yaml:\"new_admin\""]; -} - -// MsgChangeAdminResponse defines the response structure for an executed -// MsgChangeAdmin message. -message MsgChangeAdminResponse {} - -// MsgSetDenomMetadata is the sdk.Msg type for allowing an admin account to set -// the denom's bank metadata -message MsgSetDenomMetadata { - string sender = 1 [(gogoproto.moretags) = "yaml:\"sender\""]; - cosmos.bank.v1beta1.Metadata metadata = 2 [ - (gogoproto.moretags) = "yaml:\"metadata\"", - (gogoproto.nullable) = false - ]; -} - -// MsgSetDenomMetadataResponse defines the response structure for an executed -// MsgSetDenomMetadata message. -message MsgSetDenomMetadataResponse {} - -// MsgUpdateDenom is the sdk.Msg allowing an admin to update the denom -message MsgUpdateDenom { - string sender = 1 [(gogoproto.moretags) = "yaml:\"sender\""]; - string denom = 2 [(gogoproto.moretags) = "yaml:\"denom\""]; - cosmos.bank.v1beta1.AllowList allow_list = 3 [ - (gogoproto.moretags) = "yaml:\"allow_list\"", - (gogoproto.nullable) = true - ]; -} - -// MsgUpdateDenomResponse defines the response structure for an executed MsgUpdateDenom message. -message MsgUpdateDenomResponse {} diff --git a/scripts/dump_app_state_for_height.sh b/scripts/dump_app_state_for_height.sh index db20a20373..001999721e 100755 --- a/scripts/dump_app_state_for_height.sh +++ b/scripts/dump_app_state_for_height.sh @@ -28,7 +28,7 @@ fi cd $HOME sudo rm -r state_$HEIGHT mkdir state_$HEIGHT -for key in wasm epoch mint acc bank feegrant staking distribution slashing gov params upgrade evidence tokenfactory +for key in wasm epoch mint acc bank feegrant staking distribution slashing gov params upgrade evidence do $HOME/go/bin/iaviewer data $HOME/.sei/data/application.db "s/k:"$key"/" $HEIGHT > $HOME/state_$HEIGHT/$key.data $HOME/go/bin/iaviewer shape $HOME/.sei/data/application.db "s/k:"$key"/" $HEIGHT > $HOME/state_$HEIGHT/$key.shape diff --git a/sei-cosmos/proto/cosmos/bank/v1beta1/bank.proto b/sei-cosmos/proto/cosmos/bank/v1beta1/bank.proto index f9565793d4..fec4b28acc 100644 --- a/sei-cosmos/proto/cosmos/bank/v1beta1/bank.proto +++ b/sei-cosmos/proto/cosmos/bank/v1beta1/bank.proto @@ -104,6 +104,6 @@ message Metadata { message AllowList { option (gogoproto.equal) = true; - // Can be empty for no admin, or a valid sei address + // addresses is a list of bech32 account addresses. repeated string addresses = 1 [(gogoproto.moretags) = "yaml:\"addresses\""]; } diff --git a/sei-cosmos/x/bank/app_test.go b/sei-cosmos/x/bank/app_test.go index ec17b2aa26..137b2103c8 100644 --- a/sei-cosmos/x/bank/app_test.go +++ b/sei-cosmos/x/bank/app_test.go @@ -2,7 +2,6 @@ package bank_test import ( "context" - "fmt" "testing" "github.com/sei-protocol/sei-chain/app" @@ -114,142 +113,6 @@ func TestSendNotEnoughBalance(t *testing.T) { require.Equal(t, res2.GetSequence(), origSeq+1) } -func TestSendReceiverNotInAllowList(t *testing.T) { - acc := &authtypes.BaseAccount{ - Address: addr1.String(), - } - - genAccs := []authtypes.GenesisAccount{acc} - a := app.SetupWithGenesisAccounts(t, genAccs) - ctx := a.BaseApp.NewContext(false, tmproto.Header{}) - testDenom := "testDenom" - factoryDenom := fmt.Sprintf("factory/%s/%s", addr1.String(), testDenom) - - require.NoError(t, apptesting.FundAccount(a.BankKeeper, ctx, addr1, sdk.NewCoins(sdk.NewInt64Coin(factoryDenom, 100)))) - a.BankKeeper.SetDenomAllowList(ctx, factoryDenom, - types.AllowList{Addresses: []string{addr1.String()}}) - - a.Commit(context.Background()) - - res1 := a.AccountKeeper.GetAccount(ctx, addr1) - require.NotNil(t, res1) - require.Equal(t, acc, res1.(*authtypes.BaseAccount)) - - origAccNum := res1.GetAccountNumber() - origSeq := res1.GetSequence() - - sendMsg := types.NewMsgSend(addr1, addr2, sdk.Coins{sdk.NewInt64Coin(factoryDenom, 10)}) - header := tmproto.Header{ChainID: a.ChainID, Height: a.LastBlockHeight() + 1} - txGen := app.MakeEncodingConfig().TxConfig - _, _, err := app.SignCheckDeliver(t, txGen, a.BaseApp, header, []sdk.Msg{sendMsg}, []uint64{origAccNum}, []uint64{origSeq}, false, false, priv1) - require.Error(t, err) - require.Contains(t, err.Error(), fmt.Sprintf("%s is not allowed to receive funds", addr2)) - - app.CheckBalance(t, a, addr1, sdk.Coins{sdk.NewInt64Coin(factoryDenom, 100)}) -} - -func TestSendSenderAndReceiverInAllowList(t *testing.T) { - acc := &authtypes.BaseAccount{ - Address: addr1.String(), - } - - genAccs := []authtypes.GenesisAccount{acc} - a := app.SetupWithGenesisAccounts(t, genAccs) - ctx := a.BaseApp.NewContext(false, tmproto.Header{}) - testDenom := "testDenom" - factoryDenom := fmt.Sprintf("factory/%s/%s", addr1.String(), testDenom) - - require.NoError(t, apptesting.FundAccount(a.BankKeeper, ctx, addr1, sdk.NewCoins(sdk.NewInt64Coin(factoryDenom, 100)))) - a.BankKeeper.SetDenomAllowList(ctx, factoryDenom, - types.AllowList{Addresses: []string{addr1.String(), addr2.String()}}) - - a.Commit(context.Background()) - - res1 := a.AccountKeeper.GetAccount(ctx, addr1) - require.NotNil(t, res1) - require.Equal(t, acc, res1.(*authtypes.BaseAccount)) - - origAccNum := res1.GetAccountNumber() - origSeq := res1.GetSequence() - - sendMsg := types.NewMsgSend(addr1, addr2, sdk.Coins{sdk.NewInt64Coin(factoryDenom, 10)}) - header := tmproto.Header{ChainID: a.ChainID, Height: a.LastBlockHeight() + 1} - txGen := app.MakeEncodingConfig().TxConfig - _, _, err := app.SignCheckDeliver(t, txGen, a.BaseApp, header, []sdk.Msg{sendMsg}, []uint64{origAccNum}, []uint64{origSeq}, true, true, priv1) - require.NoError(t, err) - - app.CheckBalance(t, a, addr1, sdk.Coins{sdk.NewInt64Coin(factoryDenom, 90)}) - app.CheckBalance(t, a, addr2, sdk.Coins{sdk.NewInt64Coin(factoryDenom, 10)}) -} - -func TestSendWithEmptyAllowList(t *testing.T) { - acc := &authtypes.BaseAccount{ - Address: addr1.String(), - } - - genAccs := []authtypes.GenesisAccount{acc} - a := app.SetupWithGenesisAccounts(t, genAccs) - ctx := a.BaseApp.NewContext(false, tmproto.Header{}) - testDenom := "testDenom" - factoryDenom := fmt.Sprintf("factory/%s/%s", addr1.String(), testDenom) - - require.NoError(t, apptesting.FundAccount(a.BankKeeper, ctx, addr1, sdk.NewCoins(sdk.NewInt64Coin(factoryDenom, 100)))) - a.BankKeeper.SetDenomAllowList(ctx, factoryDenom, - types.AllowList{Addresses: []string{}}) - - a.Commit(context.Background()) - - res1 := a.AccountKeeper.GetAccount(ctx, addr1) - require.NotNil(t, res1) - require.Equal(t, acc, res1.(*authtypes.BaseAccount)) - - origAccNum := res1.GetAccountNumber() - origSeq := res1.GetSequence() - - sendMsg := types.NewMsgSend(addr1, addr2, sdk.Coins{sdk.NewInt64Coin(factoryDenom, 10)}) - header := tmproto.Header{ChainID: a.ChainID, Height: a.LastBlockHeight() + 1} - txGen := app.MakeEncodingConfig().TxConfig - _, _, err := app.SignCheckDeliver(t, txGen, a.BaseApp, header, []sdk.Msg{sendMsg}, []uint64{origAccNum}, []uint64{origSeq}, true, true, priv1) - require.NoError(t, err) - - app.CheckBalance(t, a, addr1, sdk.Coins{sdk.NewInt64Coin(factoryDenom, 90)}) - app.CheckBalance(t, a, addr2, sdk.Coins{sdk.NewInt64Coin(factoryDenom, 10)}) -} - -func TestSendSenderNotInAllowList(t *testing.T) { - acc := &authtypes.BaseAccount{ - Address: addr1.String(), - } - - genAccs := []authtypes.GenesisAccount{acc} - a := app.SetupWithGenesisAccounts(t, genAccs) - ctx := a.BaseApp.NewContext(false, tmproto.Header{}) - testDenom := "testDenom" - factoryDenom := fmt.Sprintf("factory/%s/%s", addr1.String(), testDenom) - - require.NoError(t, apptesting.FundAccount(a.BankKeeper, ctx, addr1, sdk.NewCoins(sdk.NewInt64Coin(factoryDenom, 100)))) - a.BankKeeper.SetDenomAllowList(ctx, factoryDenom, - types.AllowList{Addresses: []string{addr2.String()}}) - - a.Commit(context.Background()) - - res1 := a.AccountKeeper.GetAccount(ctx, addr1) - require.NotNil(t, res1) - require.Equal(t, acc, res1.(*authtypes.BaseAccount)) - - origAccNum := res1.GetAccountNumber() - origSeq := res1.GetSequence() - - sendMsg := types.NewMsgSend(addr1, addr2, sdk.Coins{sdk.NewInt64Coin(factoryDenom, 10)}) - header := tmproto.Header{ChainID: a.ChainID, Height: a.LastBlockHeight() + 1} - txGen := app.MakeEncodingConfig().TxConfig - _, _, err := app.SignCheckDeliver(t, txGen, a.BaseApp, header, []sdk.Msg{sendMsg}, []uint64{origAccNum}, []uint64{origSeq}, false, false, priv1) - require.Error(t, err) - require.Contains(t, err.Error(), fmt.Sprintf("%s is not allowed to send funds", addr1)) - - app.CheckBalance(t, a, addr1, sdk.Coins{sdk.NewInt64Coin(factoryDenom, 100)}) -} - func TestMsgMultiSendWithAccounts(t *testing.T) { acc := &authtypes.BaseAccount{ Address: addr1.String(), @@ -457,240 +320,3 @@ func TestMsgMultiSendDependent(t *testing.T) { } } } - -func TestMultiSendAllowList(t *testing.T) { - // CoinToAllowList defines a struct to map coins to their allow lists. - type CoinToAllowList struct { - fundAmount sdk.Coin - sendAmount sdk.Coin - allowList types.AllowList - } - - type testCase struct { - name string - coinsToAllowList []CoinToAllowList - sender sdk.AccAddress - receiver sdk.AccAddress - accNums []uint64 - accSeqs []uint64 - privKeys []cryptotypes.PrivKey - expectedSenderBal sdk.Coins - expectedReceiverBal sdk.Coins - expectedError bool - expectedErrorMsg string - } - - senderAcc := sdk.AccAddress(priv1.PubKey().Address()) - receiverAcc := sdk.AccAddress(priv2.PubKey().Address()) - testDenom := fmt.Sprintf("factory/%s/test", senderAcc.String()) - testDenom1 := fmt.Sprintf("factory/%s/test1", senderAcc.String()) - // Define test cases - testCases := []testCase{ - - { - name: "sender not allowed to send coins", - coinsToAllowList: []CoinToAllowList{ - { - fundAmount: sdk.NewInt64Coin(testDenom, 100), - sendAmount: sdk.NewInt64Coin(testDenom, 20), - allowList: types.AllowList{ - Addresses: []string{ - receiverAcc.String(), - }, - }, - }, - }, - accNums: []uint64{0, 2}, - accSeqs: []uint64{0, 0}, - sender: senderAcc, - receiver: receiverAcc, - privKeys: []cryptotypes.PrivKey{priv1}, - expectedSenderBal: sdk.NewCoins(sdk.NewInt64Coin(testDenom, 100)), - expectedReceiverBal: sdk.NewCoins(sdk.NewInt64Coin(testDenom, 0)), - expectedError: true, - expectedErrorMsg: fmt.Sprintf("%s is not allowed to send funds", senderAcc), - }, - { - name: "receiver not allowed to receive coins", - coinsToAllowList: []CoinToAllowList{ - { - fundAmount: sdk.NewInt64Coin(testDenom, 100), - sendAmount: sdk.NewInt64Coin(testDenom, 20), - allowList: types.AllowList{ - Addresses: []string{ - senderAcc.String(), - }, - }, - }, - }, - accNums: []uint64{0, 2}, - accSeqs: []uint64{0, 0}, - sender: senderAcc, - receiver: receiverAcc, - privKeys: []cryptotypes.PrivKey{priv1}, - expectedSenderBal: sdk.NewCoins(sdk.NewInt64Coin(testDenom, 100)), - expectedReceiverBal: sdk.NewCoins(sdk.NewInt64Coin(testDenom, 0)), - expectedError: true, - expectedErrorMsg: fmt.Sprintf("%s is not allowed to receive funds", receiverAcc), - }, - { - name: "allow list is empty (no restrictions)", - coinsToAllowList: []CoinToAllowList{ - { - fundAmount: sdk.NewInt64Coin(testDenom, 100), - sendAmount: sdk.NewInt64Coin(testDenom, 20), - allowList: types.AllowList{ - Addresses: []string{}, - }, - }, - }, - accNums: []uint64{0, 2}, - accSeqs: []uint64{0, 0}, - sender: senderAcc, - receiver: receiverAcc, - expectedSenderBal: sdk.NewCoins(sdk.NewInt64Coin(testDenom, 80)), - expectedReceiverBal: sdk.NewCoins(sdk.NewInt64Coin(testDenom, 20)), - privKeys: []cryptotypes.PrivKey{priv1}, - expectedError: false, - }, - { - name: "both sender and receiver are allowed to send and receive coins", - coinsToAllowList: []CoinToAllowList{ - { - fundAmount: sdk.NewInt64Coin(testDenom, 100), - sendAmount: sdk.NewInt64Coin(testDenom, 25), - allowList: types.AllowList{ - Addresses: []string{ - senderAcc.String(), receiverAcc.String(), - }, - }, - }, - }, - accNums: []uint64{0, 2}, - accSeqs: []uint64{0, 0}, - sender: senderAcc, - receiver: receiverAcc, - privKeys: []cryptotypes.PrivKey{priv1}, - expectedSenderBal: sdk.NewCoins(sdk.NewInt64Coin(testDenom, 75)), - expectedReceiverBal: sdk.NewCoins(sdk.NewInt64Coin(testDenom, 25)), - expectedError: false, - }, - { - name: "both are allowed for first coin, but only sender is allowed for second coin", - coinsToAllowList: []CoinToAllowList{ - { - fundAmount: sdk.NewInt64Coin(testDenom, 100), - sendAmount: sdk.NewInt64Coin(testDenom, 20), - allowList: types.AllowList{ - Addresses: []string{ - senderAcc.String(), receiverAcc.String(), - }, - }, - }, - { - fundAmount: sdk.NewInt64Coin(testDenom1, 200), - sendAmount: sdk.NewInt64Coin(testDenom1, 20), - allowList: types.AllowList{ - Addresses: []string{ - senderAcc.String(), - }, - }, - }, - }, - accNums: []uint64{0, 2}, - accSeqs: []uint64{0, 0}, - sender: senderAcc, - receiver: receiverAcc, - privKeys: []cryptotypes.PrivKey{priv1}, - expectedError: true, - expectedSenderBal: sdk.NewCoins(sdk.NewInt64Coin(testDenom, 100), sdk.NewInt64Coin(testDenom1, 200)), - expectedReceiverBal: sdk.NewCoins(sdk.NewInt64Coin(testDenom, 0), sdk.NewInt64Coin(testDenom1, 0)), - expectedErrorMsg: fmt.Sprintf("%s is not allowed to receive funds", receiverAcc), - }, - { - name: "both sender and receiver are allowed to send and receive 2 coins", - coinsToAllowList: []CoinToAllowList{ - { - fundAmount: sdk.NewInt64Coin(testDenom, 100), - sendAmount: sdk.NewInt64Coin(testDenom, 25), - allowList: types.AllowList{ - Addresses: []string{ - senderAcc.String(), receiverAcc.String(), - }, - }, - }, - { - fundAmount: sdk.NewInt64Coin(testDenom1, 200), - sendAmount: sdk.NewInt64Coin(testDenom1, 50), - allowList: types.AllowList{ - Addresses: []string{ - senderAcc.String(), receiverAcc.String(), - }, - }, - }, - }, - accNums: []uint64{0, 2}, - accSeqs: []uint64{0, 0}, - sender: senderAcc, - receiver: receiverAcc, - expectedSenderBal: sdk.NewCoins(sdk.NewInt64Coin(testDenom, 75), sdk.NewInt64Coin(testDenom1, 150)), - expectedReceiverBal: sdk.NewCoins(sdk.NewInt64Coin(testDenom, 25), sdk.NewInt64Coin(testDenom1, 50)), - privKeys: []cryptotypes.PrivKey{priv1}, - expectedError: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - // Setup genesis accounts - sender := &authtypes.BaseAccount{ - Address: tc.sender.String(), - } - receiver := &authtypes.BaseAccount{ - Address: tc.receiver.String(), - } - - genAccs := []authtypes.GenesisAccount{sender, receiver} - a := app.SetupWithGenesisAccounts(t, genAccs) - ctx := a.BaseApp.NewContext(false, tmproto.Header{}) - - msgs := make([]sdk.Msg, 0) - - for _, coinToAllowList := range tc.coinsToAllowList { - a.BankKeeper.SetDenomAllowList(ctx, coinToAllowList.fundAmount.Denom, coinToAllowList.allowList) - require.NoError(t, apptesting.FundAccount(a.BankKeeper, ctx, sender.GetAddress(), sdk.NewCoins(coinToAllowList.fundAmount))) - multiSendMsg := &types.MsgMultiSend{ - Inputs: []types.Input{ - types.NewInput(sender.GetAddress(), sdk.Coins{coinToAllowList.sendAmount}), - }, - Outputs: []types.Output{ - types.NewOutput(receiver.GetAddress(), sdk.Coins{coinToAllowList.sendAmount}), - }, - } - msgs = append(msgs, multiSendMsg) - } - - a.Commit(context.Background()) - - header := tmproto.Header{ChainID: a.ChainID, Height: a.LastBlockHeight() + 1} - txGen := app.MakeEncodingConfig().TxConfig - _, _, err := app.SignCheckDeliver(t, txGen, a.BaseApp, header, msgs, tc.accNums, tc.accSeqs, !tc.expectedError, !tc.expectedError, tc.privKeys...) - - if tc.expectedError { - require.Error(t, err, "expected an error but got none") - require.Contains(t, err.Error(), tc.expectedErrorMsg) - } else { - require.NoError(t, err, "did not expect an error but got one") - } - - // Validate balances - // Sender's balance after send should be as expected - senderBal := a.BankKeeper.GetAllBalances(ctx, tc.sender) - require.Equal(t, tc.expectedSenderBal, senderBal, "sender balance mismatch") - - // Receiver's balance after receive should be as expected - receiverBal := a.BankKeeper.GetAllBalances(ctx, tc.receiver) - require.Equal(t, tc.expectedReceiverBal, receiverBal, "receiver balance mismatch") - }) - } -} diff --git a/sei-cosmos/x/bank/keeper/keeper_test.go b/sei-cosmos/x/bank/keeper/keeper_test.go index a006d44766..cb880c76b3 100644 --- a/sei-cosmos/x/bank/keeper/keeper_test.go +++ b/sei-cosmos/x/bank/keeper/keeper_test.go @@ -23,13 +23,12 @@ import ( ) const ( - fooDenom = "foo" - barDenom = "bar" - factoryDenomPrefix = "factory" - initialPower = int64(100) - holder = "holder" - multiPerm = "multiple permissions account" - randomPerm = "random permission" + fooDenom = "foo" + barDenom = "bar" + initialPower = int64(100) + holder = "holder" + multiPerm = "multiple permissions account" + randomPerm = "random permission" ) var ( @@ -48,10 +47,6 @@ func newFooCoin(amt int64) sdk.Coin { return sdk.NewInt64Coin(fooDenom, amt) } -func newFactoryFooCoin(address sdk.AccAddress, amt int64) sdk.Coin { - return sdk.NewInt64Coin(fmt.Sprintf("%s/%s/%s", factoryDenomPrefix, address, fooDenom), amt) -} - func newBarCoin(amt int64) sdk.Coin { return sdk.NewInt64Coin(barDenom, amt) } @@ -560,166 +555,6 @@ func (suite *IntegrationTestSuite) TestSendCoins() { suite.Require().Equal(newBarCoin(25), coins[0], "expected only bar coins in the account balance, got: %v", coins) } -func (suite *IntegrationTestSuite) TestSendCoinsWithAllowList() { - app, ctx := suite.app, suite.ctx - addr1 := sdk.AccAddress("addr1_______________") - acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1) - app.AccountKeeper.SetAccount(ctx, acc1) - factoryCoin := newFactoryFooCoin(addr1, 100) - balances := sdk.NewCoins(factoryCoin, newBarCoin(50)) - suite.Require().NoError(apptesting.FundAccount(app.BankKeeper, ctx, addr1, balances)) - - addr2 := sdk.AccAddress("addr2_______________") - acc2 := app.AccountKeeper.NewAccountWithAddress(ctx, addr2) - app.AccountKeeper.SetAccount(ctx, acc2) - - app.BankKeeper.SetDenomAllowList(ctx, factoryCoin.Denom, - types.AllowList{Addresses: []string{addr1.String(), addr2.String()}}) - - sendAmt := sdk.NewCoins(newFactoryFooCoin(addr1, 40), newBarCoin(25)) - suite.Require().NoError(app.BankKeeper.SendCoins(ctx, addr1, addr2, sendAmt)) - - acc1Balances := app.BankKeeper.GetAllBalances(ctx, addr1) - expected := sdk.NewCoins(newFactoryFooCoin(addr1, 60), newBarCoin(25)) - suite.Require().Equal(expected, acc1Balances) - - acc2Balances := app.BankKeeper.GetAllBalances(ctx, addr2) - expected = sdk.NewCoins(newFactoryFooCoin(addr1, 40), newBarCoin(25)) - suite.Require().Equal(expected, acc2Balances) -} - -// Test that creating allowlist does not block module to module transfers -func (suite *IntegrationTestSuite) TestSendCoinsModuleToModuleWithAllowList() { - // add module accounts to supply keeper - ctx := suite.ctx - _, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool)) - app := suite.app - app.BankKeeper = keeper - - addr1 := sdk.AccAddress("addr1_______________") - acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1) - app.AccountKeeper.SetAccount(ctx, acc1) - factoryCoin := newFactoryFooCoin(addr1, 100) - balances := sdk.NewCoins(factoryCoin, newBarCoin(50)) - app.BankKeeper.SetDenomAllowList(ctx, factoryCoin.Denom, types.AllowList{ - Addresses: []string{addr1.String()}}) - - // set up bank balances - suite.Require().NoError(apptesting.FundAccount(app.BankKeeper, ctx, multiPermAcc.GetAddress(), balances)) - - sendCoins := sdk.NewCoins(newFactoryFooCoin(addr1, 50), newBarCoin(20)) - suite.Require().NoError(app.BankKeeper.SendCoinsFromModuleToModule(ctx, multiPerm, randomPerm, sendCoins)) - expectedBankBalances := sdk.NewCoins(newFactoryFooCoin(addr1, 50), newBarCoin(30)) - // assert module balances correct - bals := app.BankKeeper.GetAllBalances(ctx, multiPermAcc.GetAddress()) - suite.Require().Equal(expectedBankBalances, bals) - // assert receiver balances correct - userBals := app.BankKeeper.GetAllBalances(ctx, randomPermAcc.GetAddress()) - suite.Require().Equal(sendCoins, userBals) -} - -// Test that creating allowlist does not block sending from module to account even though we are not explicitly adding -// the module account to the allowlist -func (suite *IntegrationTestSuite) TestSendCoinsModuleToAccountWithAllowList() { - // add module accounts to supply keeper - ctx := suite.ctx - moduleAddresses := make(map[string]bool) - moduleAddresses[multiPermAcc.GetAddress().String()] = true - moduleAddresses[suite.app.AccountKeeper.GetModuleAddress("mint").String()] = true - _, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool)) - app := suite.app - app.BankKeeper = keeper - - addr1 := sdk.AccAddress("addr1_______________") - acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1) - app.AccountKeeper.SetAccount(ctx, acc1) - factoryCoin := newFactoryFooCoin(addr1, 100) - balances := sdk.NewCoins(factoryCoin, newBarCoin(50)) - app.BankKeeper.SetDenomAllowList(ctx, factoryCoin.Denom, types.AllowList{ - Addresses: []string{addr1.String()}}) - - // set up bank balances - suite.Require().NoError(apptesting.FundAccount(app.BankKeeper, ctx, multiPermAcc.GetAddress(), balances)) - - sendCoins := sdk.NewCoins(newFactoryFooCoin(addr1, 50), newBarCoin(20)) - suite.Require().NoError(app.BankKeeper.SendCoinsFromModuleToAccount(ctx, multiPerm, addr1, sendCoins)) - - expectedBankBalances := sdk.NewCoins(newFactoryFooCoin(addr1, 50), newBarCoin(30)) - // assert module balances correct - bals := app.BankKeeper.GetAllBalances(ctx, multiPermAcc.GetAddress()) - suite.Require().Equal(expectedBankBalances, bals) - // assert receiver balances correct - userBals := app.BankKeeper.GetAllBalances(ctx, addr1) - suite.Require().Equal(sendCoins, userBals) -} - -// Test that creating allowlist does not block sending from account to module even though we are not explicitly adding -// the module account to the allowlist -func (suite *IntegrationTestSuite) TestSendCoinsAccountToModuleWithAllowList() { - // add module accounts to supply keeper - ctx := suite.ctx - moduleAddresses := make(map[string]bool) - moduleAddresses[multiPermAcc.GetAddress().String()] = true - moduleAddresses[suite.app.AccountKeeper.GetModuleAddress("mint").String()] = true - _, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool)) - app := suite.app - app.BankKeeper = keeper - - addr1 := sdk.AccAddress("addr1_______________") - acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1) - app.AccountKeeper.SetAccount(ctx, acc1) - factoryCoin := newFactoryFooCoin(addr1, 100) - balances := sdk.NewCoins(factoryCoin, newBarCoin(50)) - app.BankKeeper.SetDenomAllowList(ctx, factoryCoin.Denom, types.AllowList{ - Addresses: []string{addr1.String()}}) - - // set up bank balances - suite.Require().NoError(apptesting.FundAccount(app.BankKeeper, ctx, addr1, balances)) - - sendCoins := sdk.NewCoins(newFactoryFooCoin(addr1, 50), newBarCoin(20)) - suite.Require().NoError(app.BankKeeper.SendCoinsFromAccountToModule(ctx, addr1, multiPerm, sendCoins)) - expectedBankBalances := sdk.NewCoins(newFactoryFooCoin(addr1, 50), newBarCoin(30)) - // assert account balances correct - bals := app.BankKeeper.GetAllBalances(ctx, addr1) - suite.Require().Equal(expectedBankBalances, bals) - // assert module balances correct - userBals := app.BankKeeper.GetAllBalances(ctx, multiPermAcc.GetAddress()) - suite.Require().Equal(sendCoins, userBals) -} - -// Test that creating allowlist does not block sending from account to module even though we are not explicitly adding -// the module account to the allowlist -func (suite *IntegrationTestSuite) TestDeferredSendCoinsAccountToModuleWithAllowList() { - // add module accounts to supply keeper - ctx := suite.ctx - _, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool)) - app := suite.app - app.BankKeeper = keeper - - addr1 := sdk.AccAddress("addr1_______________") - acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1) - app.AccountKeeper.SetAccount(ctx, acc1) - factoryCoin := newFactoryFooCoin(addr1, 100) - balances := sdk.NewCoins(factoryCoin, newBarCoin(50)) - app.BankKeeper.SetDenomAllowList(ctx, factoryCoin.Denom, types.AllowList{ - Addresses: []string{addr1.String()}}) - - // set up bank balances - suite.Require().NoError(apptesting.FundAccount(app.BankKeeper, ctx, addr1, balances)) - - sendCoins := sdk.NewCoins(newFactoryFooCoin(addr1, 50), newBarCoin(20)) - suite.Require().NoError(app.BankKeeper.DeferredSendCoinsFromAccountToModule(ctx, addr1, multiPerm, sendCoins)) - app.BankKeeper.WriteDeferredBalances(ctx) - - expectedBankBalances := sdk.NewCoins(newFactoryFooCoin(addr1, 50), newBarCoin(30)) - // assert account balances correct - bals := app.BankKeeper.GetAllBalances(ctx, addr1) - suite.Require().Equal(expectedBankBalances, bals) - // assert module balances correct - userBals := app.BankKeeper.GetAllBalances(ctx, multiPermAcc.GetAddress()) - suite.Require().Equal(sendCoins, userBals) -} - func (suite *IntegrationTestSuite) TestSendCoinsModuleToAccount() { // add module accounts to supply keeper ctx := suite.ctx @@ -1421,180 +1256,6 @@ func (suite *IntegrationTestSuite) TestSetDenomMetaData() { suite.Require().Equal(metadata[1].GetDenomUnits()[1].GetAliases(), actualMetadata.GetDenomUnits()[1].GetAliases()) } -func (suite *IntegrationTestSuite) TestSetAllowList() { - app, ctx := suite.app, suite.ctx - - allowList := types.AllowList{Addresses: []string{"addr1", "addr2"}} - ownerAddress := sdk.AccAddress("owner") - denom := "factory/" + ownerAddress.String() + "/Test" - - app.BankKeeper.SetDenomAllowList(ctx, denom, allowList) - - actualAllowList := app.BankKeeper.GetDenomAllowList(ctx, denom) - suite.Require().Equal(allowList, actualAllowList) -} - -func (suite *IntegrationTestSuite) TestBaseKeeper_IsAllowedToSendCoins() { - type CoinToAllowList struct { - coin sdk.Coin - allowList types.AllowList - } - type args struct { - addr sdk.AccAddress - coinsToAllowList []CoinToAllowList - } - tests := []struct { - name string - args args - isAllowed bool - }{ - { - name: "Allowed for for empty coins", - args: args{ - addr: sdk.AccAddress{}, - coinsToAllowList: []CoinToAllowList{ - {coin: sdk.Coin{}}, - }, - }, - isAllowed: true, - }, - { - name: "allowed for to transfer with a non-factory coin", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin("test", 100), - }, - }, - }, - isAllowed: true, - }, - { - name: "allowed with a factory coin with no allow list", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin( - fmt.Sprintf("factory/%s/test", sdk.AccAddress("from")), 100), - }, - }, - }, - isAllowed: true, - }, - { - name: "allowed with a factory coin with empty allow list", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin( - fmt.Sprintf("factory/%s/test", sdk.AccAddress("from")), 100), - allowList: types.AllowList{}, - }, - }, - }, - isAllowed: true, - }, - { - name: "not allowed to transfer coins for denom if not in allowlist", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin(fmt.Sprintf("factory/%s/test", sdk.AccAddress("from")), 100), - allowList: types.AllowList{ - Addresses: []string{sdk.AccAddress("other").String()}, - }, - }, - }, - }, - isAllowed: false, - }, - { - name: "allowed to transfer for denom", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin(fmt.Sprintf("factory/%s/test", sdk.AccAddress("from")), 100), - allowList: types.AllowList{ - Addresses: []string{sdk.AccAddress("from").String(), sdk.AccAddress("to").String()}, - }, - }, - }, - }, - isAllowed: true, - }, - { - name: "allowed for one coin but not allowed for another coin", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin(fmt.Sprintf("factory/%s/test", sdk.AccAddress("from")), 100), - allowList: types.AllowList{ - Addresses: []string{sdk.AccAddress("from").String(), sdk.AccAddress("to").String()}, - }, - }, - { - coin: sdk.NewInt64Coin(fmt.Sprintf("factory/%s/test2", sdk.AccAddress("from")), 100), - allowList: types.AllowList{ - Addresses: []string{sdk.AccAddress("other").String(), sdk.AccAddress("yetanother").String()}, - }, - }, - }, - }, - isAllowed: false, - }, - { - name: "not allowed for first coin but allowed for another coin", - args: args{ - addr: sdk.AccAddress("from"), - coinsToAllowList: []CoinToAllowList{ - { - coin: sdk.NewInt64Coin(fmt.Sprintf("factory/%s/test", sdk.AccAddress("from")), 100), - allowList: types.AllowList{ - Addresses: []string{sdk.AccAddress("other").String(), sdk.AccAddress("yetanother").String()}, - }, - }, - { - coin: sdk.NewInt64Coin(fmt.Sprintf("factory/%s/test2", sdk.AccAddress("from")), 100), - allowList: types.AllowList{ - Addresses: []string{sdk.AccAddress("from").String(), sdk.AccAddress("to").String()}, - }, - }, - }, - }, - isAllowed: false, - }, - } - - for _, tt := range tests { - suite.Run(tt.name, func() { - app, ctx := suite.app, suite.ctx - coins := sdk.NewCoins() - for _, coinToAllowList := range tt.args.coinsToAllowList { - if coinToAllowList.coin.Denom != "" { - coins = coins.Add(coinToAllowList.coin) - if coinToAllowList.allowList.Addresses != nil { - app.BankKeeper.SetDenomAllowList(ctx, coinToAllowList.coin.Denom, coinToAllowList.allowList) - } - } - } - denomToAllowedAddressesCache := make(map[string]keeper.AllowedAddresses) - isAllowed := - app.BankKeeper.IsInDenomAllowList(ctx, tt.args.addr, coins, denomToAllowedAddressesCache) - - // Use suite.Require to assert the results - suite.Require().Equal(tt.isAllowed, isAllowed, - fmt.Errorf("IsInDenomAllowList() isAllowed = %v, want %v", - isAllowed, tt.isAllowed)) - }) - } -} - func (suite *IntegrationTestSuite) TestCanSendTo() { app, ctx := suite.app, suite.ctx badAddr := sdk.AccAddress([]byte("addr1_______________")) diff --git a/sei-cosmos/x/bank/keeper/msg_server.go b/sei-cosmos/x/bank/keeper/msg_server.go index 867c570441..23115e50d7 100644 --- a/sei-cosmos/x/bank/keeper/msg_server.go +++ b/sei-cosmos/x/bank/keeper/msg_server.go @@ -39,12 +39,7 @@ func (k msgServer) Send(goCtx context.Context, msg *types.MsgSend) (*types.MsgSe return nil, err } - allowListCache := make(map[string]AllowedAddresses) - if !k.IsInDenomAllowList(ctx, from, msg.Amount, allowListCache) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to send funds", msg.FromAddress) - } - - if k.BlockedAddr(to) || !k.IsInDenomAllowList(ctx, to, msg.Amount, allowListCache) { + if k.BlockedAddr(to) { return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", msg.ToAddress) } @@ -73,22 +68,17 @@ func (k msgServer) Send(goCtx context.Context, msg *types.MsgSend) (*types.MsgSe func (k msgServer) MultiSend(goCtx context.Context, msg *types.MsgMultiSend) (*types.MsgMultiSendResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - denomToAllowListCache := make(map[string]AllowedAddresses) // NOTE: totalIn == totalOut should already have been checked for _, in := range msg.Inputs { if err := k.IsSendEnabledCoins(ctx, in.Coins...); err != nil { return nil, err } - accAddr := sdk.MustAccAddressFromBech32(in.Address) - if !k.IsInDenomAllowList(ctx, accAddr, in.Coins, denomToAllowListCache) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to send funds", accAddr) - } } for _, out := range msg.Outputs { accAddr := sdk.MustAccAddressFromBech32(out.Address) - if k.BlockedAddr(accAddr) || !k.IsInDenomAllowList(ctx, accAddr, out.Coins, denomToAllowListCache) { + if k.BlockedAddr(accAddr) { return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", out.Address) } } diff --git a/sei-cosmos/x/bank/keeper/send.go b/sei-cosmos/x/bank/keeper/send.go index b525e77a03..4a04145ed8 100644 --- a/sei-cosmos/x/bank/keeper/send.go +++ b/sei-cosmos/x/bank/keeper/send.go @@ -6,7 +6,6 @@ import ( "fmt" "os" "runtime/debug" - "strings" "github.com/sei-protocol/sei-chain/sei-cosmos/codec" "github.com/sei-protocol/sei-chain/sei-cosmos/store/prefix" @@ -16,10 +15,6 @@ import ( paramtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/params/types" ) -const ( - TokenFactoryPrefix = "factory" -) - var CoinbaseAddressPrefix = []byte("evm_coinbase") // SendKeeper defines a module interface that facilitates the transfer of coins @@ -41,9 +36,6 @@ type SendKeeper interface { IsSendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error - SetDenomAllowList(ctx sdk.Context, denom string, allowList types.AllowList) - GetDenomAllowList(ctx sdk.Context, denom string) types.AllowList - IsInDenomAllowList(ctx sdk.Context, addr sdk.AccAddress, coins sdk.Coins, cache map[string]AllowedAddresses) bool BlockedAddr(addr sdk.AccAddress) bool RegisterRecipientChecker(RecipientChecker) @@ -471,83 +463,3 @@ func (k BaseSendKeeper) CanSendTo(ctx sdk.Context, recipient sdk.AccAddress) boo func SplitUseiWeiAmount(amt sdk.Int) (sdk.Int, sdk.Int) { return amt.Quo(OneUseiInWei), amt.Mod(OneUseiInWei) } - -func (k BaseSendKeeper) SetDenomAllowList(ctx sdk.Context, denom string, allowList types.AllowList) { - store := ctx.KVStore(k.storeKey) - denomAllowListStore := prefix.NewStore(store, types.DenomAllowListKey(denom)) - - m := k.cdc.MustMarshal(&allowList) - denomAllowListStore.Set([]byte(denom), m) -} - -func (k BaseSendKeeper) GetDenomAllowList(ctx sdk.Context, denom string) types.AllowList { - store := ctx.KVStore(k.storeKey) - store = prefix.NewStore(store, types.DenomAllowListKey(denom)) - - bz := store.Get([]byte(denom)) - if bz == nil { - return types.AllowList{} - } - - var allowList types.AllowList - k.cdc.MustUnmarshal(bz, &allowList) - - return allowList -} - -// IsInDenomAllowList checks if the given address is allowed to send the given coins. -// The check is performed only fot token factory denoms. For each token factory denom, -// it checks if there is allow list for the given denom. If there is no allow list, -// the address is allowed to send the coins. If there is an allow list, the address is -// allowed to send the coins only if it is in the allow list. -func (k BaseSendKeeper) IsInDenomAllowList(ctx sdk.Context, addr sdk.AccAddress, coins sdk.Coins, cache map[string]AllowedAddresses) bool { - for _, coin := range coins { - // Skip if denom does not contain the token factory prefix - if !strings.HasPrefix(coin.Denom, TokenFactoryPrefix) { - continue - } - - allowedAddresses := k.getAllowedAddresses(ctx, cache, coin.Denom) - // skip if there is no allow list for the denom - if len(allowedAddresses.set) == 0 { - continue - } - - if !allowedAddresses.contains(addr) { - return false - } - } - return true -} - -func (k BaseSendKeeper) getAllowedAddresses(ctx sdk.Context, cache map[string]AllowedAddresses, denom string) AllowedAddresses { - allowedAddresses, exists := cache[denom] - if !exists { - allowList := k.GetDenomAllowList(ctx, denom) - allowedAddresses = k.buildAllowedAddressesMap(allowList) - // we cache even if the allowList is empty to avoid multiple db reads - cache[denom] = allowedAddresses - } - return allowedAddresses -} - -type AllowedAddresses struct { - set map[string]struct{} -} - -func (a AllowedAddresses) contains(address sdk.AccAddress) bool { - _, exists := a.set[address.String()] - return exists -} - -func (k BaseSendKeeper) buildAllowedAddressesMap(allowList types.AllowList) AllowedAddresses { - allowedAddressesMap := make(map[string]struct{}) - if len(allowList.Addresses) > 0 { - for _, addr := range allowList.Addresses { - allowedAddressesMap[addr] = struct{}{} - } - } - return AllowedAddresses{ - set: allowedAddressesMap, - } -} diff --git a/sei-cosmos/x/bank/types/bank.pb.go b/sei-cosmos/x/bank/types/bank.pb.go index 452de38b55..61a2ddada3 100644 --- a/sei-cosmos/x/bank/types/bank.pb.go +++ b/sei-cosmos/x/bank/types/bank.pb.go @@ -418,7 +418,7 @@ func (m *Metadata) GetSymbol() string { } type AllowList struct { - // Can be empty for no admin, or a valid sei address + // addresses is a list of bech32 account addresses. Addresses []string `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty" yaml:"addresses"` } diff --git a/sei-cosmos/x/bank/types/key.go b/sei-cosmos/x/bank/types/key.go index bc55c3bdb8..a4a1def783 100644 --- a/sei-cosmos/x/bank/types/key.go +++ b/sei-cosmos/x/bank/types/key.go @@ -32,7 +32,7 @@ var ( BalancesPrefix = []byte{0x02} SupplyKey = []byte{0x00} DenomMetadataPrefix = []byte{0x1} - DenomAllowListPrefix = []byte{0x11} + DenomAllowListPrefix = []byte{0x11} // deprecated ) // DenomMetadataKey returns the denomination metadata key. @@ -41,12 +41,6 @@ func DenomMetadataKey(denom string) []byte { return append(DenomMetadataPrefix, d...) } -// DenomAllowListKey returns the denomination allow list key. -func DenomAllowListKey(denom string) []byte { - d := []byte(denom) - return append(DenomAllowListPrefix, d...) -} - // AddressFromBalancesStore returns an account address from a balances prefix // store. The key must not contain the prefix BalancesPrefix as the prefix store // iterator discards the actual prefix. diff --git a/sei-db/common/keys/store_keys.go b/sei-db/common/keys/store_keys.go index f84f4fe452..577126f870 100644 --- a/sei-db/common/keys/store_keys.go +++ b/sei-db/common/keys/store_keys.go @@ -25,7 +25,6 @@ const ( EVMStoreKey = "evm" // x/evm/types.StoreKey WasmStoreKey = "wasm" // sei-wasmd/x/wasm/types.StoreKey EpochStoreKey = "epoch" // x/epoch/types.StoreKey - TokenfactoryStoreKey = "tokenfactory" // x/tokenfactory/types.StoreKey ) // MemIAVLStoreKeys is the canonical list of module KV store keys that are @@ -48,7 +47,6 @@ var MemIAVLStoreKeys = []string{ EVMStoreKey, WasmStoreKey, EpochStoreKey, - TokenfactoryStoreKey, } // memIAVLStoreKeySet is MemIAVLStoreKeys materialized as a set for O(1) diff --git a/sei-db/tools/cmd/seidb/operations/module.go b/sei-db/tools/cmd/seidb/operations/module.go index 5a554f0c81..5351a0867f 100644 --- a/sei-db/tools/cmd/seidb/operations/module.go +++ b/sei-db/tools/cmd/seidb/operations/module.go @@ -1,5 +1,5 @@ package operations var AllModules = []string{ - "evm", "wasm", "epoch", "mint", "acc", "bank", "feegrant", "staking", "distribution", "slashing", "gov", "params", "upgrade", "evidence", "tokenfactory", + "evm", "wasm", "epoch", "mint", "acc", "bank", "feegrant", "staking", "distribution", "slashing", "gov", "params", "upgrade", "evidence", } diff --git a/tools/utils/helper.go b/tools/utils/helper.go index 4466443d3b..45c64a45dd 100644 --- a/tools/utils/helper.go +++ b/tools/utils/helper.go @@ -19,7 +19,6 @@ import ( epochmoduletypes "github.com/sei-protocol/sei-chain/x/epoch/types" evmtypes "github.com/sei-protocol/sei-chain/x/evm/types" minttypes "github.com/sei-protocol/sei-chain/x/mint/types" - tokenfactorytypes "github.com/sei-protocol/sei-chain/x/tokenfactory/types" ) var ModuleKeys = sdk.NewKVStoreKeys( @@ -27,7 +26,7 @@ var ModuleKeys = sdk.NewKVStoreKeys( minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, paramstypes.StoreKey, upgradetypes.StoreKey, seidbkeys.FeegrantStoreKey, evidencetypes.StoreKey, - evmtypes.StoreKey, wasm.StoreKey, epochmoduletypes.StoreKey, tokenfactorytypes.StoreKey, + evmtypes.StoreKey, wasm.StoreKey, epochmoduletypes.StoreKey, ) var Modules = []string{ @@ -44,7 +43,6 @@ var Modules = []string{ "params", "slashing", "staking", - "tokenfactory", "upgrade", "wasm"} diff --git a/wasmbinding/bindings/msg.go b/wasmbinding/bindings/msg.go index 4b943d20a1..10d047759b 100644 --- a/wasmbinding/bindings/msg.go +++ b/wasmbinding/bindings/msg.go @@ -2,38 +2,8 @@ package bindings import ( sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" ) -// / CreateDenom creates a new factory denom, of denomination: -// / factory/{creating contract address}/{Subdenom} -// / Subdenom can be of length at most 44 characters, in [0-9a-zA-Z./] -// / The (creating contract address, subdenom) pair must be unique. -// / The created denom's admin is the creating contract address, -// / but this admin can be changed using the ChangeAdmin binding. -type CreateDenom struct { - Subdenom string `json:"subdenom"` -} - -// / ChangeAdmin changes the admin for a factory denom. -// / If the NewAdminAddress is empty, the denom has no admin. -type ChangeAdmin struct { - Denom string `json:"denom"` - NewAdminAddress string `json:"new_admin_address"` -} - -type SetMetadata struct { - Metadata banktypes.Metadata `json:"metadata"` -} - -type MintTokens struct { - Amount sdk.Coin `json:"amount"` -} - -type BurnTokens struct { - Amount sdk.Coin `json:"amount"` -} - type CallEVM struct { Value *sdk.Int `json:"value"` To string `json:"to"` diff --git a/wasmbinding/encoder.go b/wasmbinding/encoder.go index 20b369886f..a03ed5c239 100644 --- a/wasmbinding/encoder.go +++ b/wasmbinding/encoder.go @@ -8,15 +8,9 @@ import ( wasmtypes "github.com/sei-protocol/sei-chain/sei-wasmd/x/wasm/types" wasmvmtypes "github.com/sei-protocol/sei-chain/sei-wasmvm/types" evmwasm "github.com/sei-protocol/sei-chain/x/evm/client/wasm" - tokenfactorywasm "github.com/sei-protocol/sei-chain/x/tokenfactory/client/wasm" ) type SeiWasmMessage struct { - CreateDenom json.RawMessage `json:"create_denom,omitempty"` - MintTokens json.RawMessage `json:"mint_tokens,omitempty"` - BurnTokens json.RawMessage `json:"burn_tokens,omitempty"` - ChangeAdmin json.RawMessage `json:"change_admin,omitempty"` - SetMetadata json.RawMessage `json:"set_metadata,omitempty"` CallEVM json.RawMessage `json:"call_evm,omitempty"` DelegateCallEVM json.RawMessage `json:"delegate_call_evm,omitempty"` } @@ -27,16 +21,6 @@ func CustomEncoder(sender sdk.AccAddress, msg json.RawMessage, info wasmvmtypes. return []sdk.Msg{}, sdkerrors.Wrap(err, "Error parsing Sei Wasm Message") } switch { - case parsedMessage.CreateDenom != nil: - return tokenfactorywasm.EncodeTokenFactoryCreateDenom(parsedMessage.CreateDenom, sender) - case parsedMessage.MintTokens != nil: - return tokenfactorywasm.EncodeTokenFactoryMint(parsedMessage.MintTokens, sender) - case parsedMessage.BurnTokens != nil: - return tokenfactorywasm.EncodeTokenFactoryBurn(parsedMessage.BurnTokens, sender) - case parsedMessage.ChangeAdmin != nil: - return tokenfactorywasm.EncodeTokenFactoryChangeAdmin(parsedMessage.ChangeAdmin, sender) - case parsedMessage.SetMetadata != nil: - return tokenfactorywasm.EncodeTokenFactorySetMetadata(parsedMessage.SetMetadata, sender) case parsedMessage.CallEVM != nil: return evmwasm.EncodeCallEVM(parsedMessage.CallEVM, sender, info) case parsedMessage.DelegateCallEVM != nil: diff --git a/wasmbinding/queries.go b/wasmbinding/queries.go index b540a8830a..c7dd8e8941 100644 --- a/wasmbinding/queries.go +++ b/wasmbinding/queries.go @@ -14,25 +14,20 @@ import ( epochtypes "github.com/sei-protocol/sei-chain/x/epoch/types" evmwasm "github.com/sei-protocol/sei-chain/x/evm/client/wasm" evmbindings "github.com/sei-protocol/sei-chain/x/evm/client/wasm/bindings" - tokenfactorywasm "github.com/sei-protocol/sei-chain/x/tokenfactory/client/wasm" - tokenfactorybindings "github.com/sei-protocol/sei-chain/x/tokenfactory/client/wasm/bindings" - tokenfactorytypes "github.com/sei-protocol/sei-chain/x/tokenfactory/types" ) type QueryPlugin struct { - epochHandler epochwasm.EpochWasmQueryHandler - tokenfactoryHandler tokenfactorywasm.TokenFactoryWasmQueryHandler - evmHandler evmwasm.EVMQueryHandler - stakingKeeper stakingkeeper.Keeper + epochHandler epochwasm.EpochWasmQueryHandler + evmHandler evmwasm.EVMQueryHandler + stakingKeeper stakingkeeper.Keeper } // NewQueryPlugin returns a reference to a new QueryPlugin. -func NewQueryPlugin(eh *epochwasm.EpochWasmQueryHandler, th *tokenfactorywasm.TokenFactoryWasmQueryHandler, evmh *evmwasm.EVMQueryHandler, sk stakingkeeper.Keeper) *QueryPlugin { +func NewQueryPlugin(eh *epochwasm.EpochWasmQueryHandler, evmh *evmwasm.EVMQueryHandler, sk stakingkeeper.Keeper) *QueryPlugin { return &QueryPlugin{ - epochHandler: *eh, - tokenfactoryHandler: *th, - evmHandler: *evmh, - stakingKeeper: sk, + epochHandler: *eh, + evmHandler: *evmh, + stakingKeeper: sk, } } @@ -58,39 +53,6 @@ func (qp QueryPlugin) HandleEpochQuery(ctx sdk.Context, queryData json.RawMessag } } -func (qp QueryPlugin) HandleTokenFactoryQuery(ctx sdk.Context, queryData json.RawMessage) ([]byte, error) { - var parsedQuery tokenfactorybindings.SeiTokenFactoryQuery - if err := json.Unmarshal(queryData, &parsedQuery); err != nil { - return nil, tokenfactorytypes.ErrParsingSeiTokenFactoryQuery - } - switch { - case parsedQuery.DenomAuthorityMetadata != nil: - res, err := qp.tokenfactoryHandler.GetDenomAuthorityMetadata(ctx, parsedQuery.DenomAuthorityMetadata) - if err != nil { - return nil, err - } - bz, err := json.Marshal(res) - if err != nil { - return nil, tokenfactorytypes.ErrEncodingDenomAuthorityMetadata - } - - return bz, nil - case parsedQuery.DenomsFromCreator != nil: - res, err := qp.tokenfactoryHandler.GetDenomsFromCreator(ctx, parsedQuery.DenomsFromCreator) - if err != nil { - return nil, err - } - bz, err := json.Marshal(res) - if err != nil { - return nil, tokenfactorytypes.ErrEncodingDenomsFromCreator - } - - return bz, nil - default: - return nil, tokenfactorytypes.ErrUnknownSeiTokenFactoryQuery - } -} - func (qp QueryPlugin) HandleEVMQuery(ctx sdk.Context, queryData json.RawMessage) (res []byte, err error) { var queryType evmbindings.EVMQueryType var parsedQuery evmbindings.SeiEVMQuery diff --git a/wasmbinding/query_plugin.go b/wasmbinding/query_plugin.go index 3d57907445..021a22c940 100644 --- a/wasmbinding/query_plugin.go +++ b/wasmbinding/query_plugin.go @@ -9,10 +9,9 @@ import ( ) const ( - EpochRoute = "epoch" - TokenFactoryRoute = "tokenfactory" - EVMRoute = "evm" - StakingExtRoute = "stakingext" + EpochRoute = "epoch" + EVMRoute = "evm" + StakingExtRoute = "stakingext" ) type SeiQueryWrapper struct { @@ -31,8 +30,6 @@ func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessag switch contractQuery.Route { case EpochRoute: return qp.HandleEpochQuery(ctx, contractQuery.QueryData) - case TokenFactoryRoute: - return qp.HandleTokenFactoryQuery(ctx, contractQuery.QueryData) case EVMRoute: return qp.HandleEVMQuery(ctx, contractQuery.QueryData) case StakingExtRoute: diff --git a/wasmbinding/test/encoder_test.go b/wasmbinding/test/encoder_test.go index 2fc786819a..bc7a3c1188 100644 --- a/wasmbinding/test/encoder_test.go +++ b/wasmbinding/test/encoder_test.go @@ -5,95 +5,25 @@ import ( "testing" sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - "github.com/sei-protocol/sei-chain/wasmbinding/bindings" - tokenfactorywasm "github.com/sei-protocol/sei-chain/x/tokenfactory/client/wasm" - tokenfactorytypes "github.com/sei-protocol/sei-chain/x/tokenfactory/types" + wasmtypes "github.com/sei-protocol/sei-chain/sei-wasmd/x/wasm/types" + wasmvmtypes "github.com/sei-protocol/sei-chain/sei-wasmvm/types" + "github.com/sei-protocol/sei-chain/wasmbinding" "github.com/stretchr/testify/require" ) -const ( - TEST_TARGET_CONTRACT = "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m" - TEST_CREATOR = "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw" -) - -func TestEncodeCreateDenom(t *testing.T) { - contractAddr, err := sdk.AccAddressFromBech32("sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw") - require.NoError(t, err) - msg := bindings.CreateDenom{ - Subdenom: "subdenom", - } - serializedMsg, _ := json.Marshal(msg) - - decodedMsgs, err := tokenfactorywasm.EncodeTokenFactoryCreateDenom(serializedMsg, contractAddr) - require.NoError(t, err) - require.Equal(t, 1, len(decodedMsgs)) - typedDecodedMsg, ok := decodedMsgs[0].(*tokenfactorytypes.MsgCreateDenom) - require.True(t, ok) - expectedMsg := tokenfactorytypes.MsgCreateDenom{ - Sender: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - Subdenom: "subdenom", - } - require.Equal(t, expectedMsg, *typedDecodedMsg) -} - -func TestEncodeMint(t *testing.T) { - contractAddr, err := sdk.AccAddressFromBech32("sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw") - require.NoError(t, err) - msg := bindings.MintTokens{ - Amount: sdk.Coin{Amount: sdk.NewInt(100), Denom: "subdenom"}, - } - serializedMsg, _ := json.Marshal(msg) - - decodedMsgs, err := tokenfactorywasm.EncodeTokenFactoryMint(serializedMsg, contractAddr) - require.NoError(t, err) - require.Equal(t, 1, len(decodedMsgs)) - typedDecodedMsg, ok := decodedMsgs[0].(*tokenfactorytypes.MsgMint) - require.True(t, ok) - expectedMsg := tokenfactorytypes.MsgMint{ - Sender: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - Amount: sdk.Coin{Amount: sdk.NewInt(100), Denom: "subdenom"}, - } - require.Equal(t, expectedMsg, *typedDecodedMsg) -} - -func TestEncodeBurn(t *testing.T) { - contractAddr, err := sdk.AccAddressFromBech32("sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw") - require.NoError(t, err) - msg := bindings.BurnTokens{ - Amount: sdk.Coin{Amount: sdk.NewInt(10), Denom: "subdenom"}, - } - serializedMsg, _ := json.Marshal(msg) - - decodedMsgs, err := tokenfactorywasm.EncodeTokenFactoryBurn(serializedMsg, contractAddr) - require.NoError(t, err) - require.Equal(t, 1, len(decodedMsgs)) - typedDecodedMsg, ok := decodedMsgs[0].(*tokenfactorytypes.MsgBurn) - require.True(t, ok) - expectedMsg := tokenfactorytypes.MsgBurn{ - Sender: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - Amount: sdk.Coin{Amount: sdk.NewInt(10), Denom: "subdenom"}, - } - require.Equal(t, expectedMsg, *typedDecodedMsg) -} - -func TestEncodeChangeAdmin(t *testing.T) { - contractAddr, err := sdk.AccAddressFromBech32("sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw") - require.NoError(t, err) - msg := bindings.ChangeAdmin{ - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/subdenom", - NewAdminAddress: "sei1hjfwcza3e3uzeznf3qthhakdr9juetl7g6esl4", - } - serializedMsg, _ := json.Marshal(msg) - - decodedMsgs, err := tokenfactorywasm.EncodeTokenFactoryChangeAdmin(serializedMsg, contractAddr) - require.NoError(t, err) - require.Equal(t, 1, len(decodedMsgs)) - typedDecodedMsg, ok := decodedMsgs[0].(*tokenfactorytypes.MsgChangeAdmin) - require.True(t, ok) - expectedMsg := tokenfactorytypes.MsgChangeAdmin{ - Sender: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/subdenom", - NewAdmin: "sei1hjfwcza3e3uzeznf3qthhakdr9juetl7g6esl4", +// TestCustomEncoderRefusesTokenfactoryMessages requires every tokenfactory custom +// message a contract can send to be refused as an unknown Sei message. +func TestCustomEncoderRefusesTokenfactoryMessages(t *testing.T) { + sender := sdk.AccAddress("tokenfactory-sender1") + for _, msg := range []string{ + `{"create_denom":{"subdenom":"subdenom"}}`, + `{"mint_tokens":{"amount":{"denom":"factory/creator/subdenom","amount":"100"}}}`, + `{"burn_tokens":{"amount":{"denom":"factory/creator/subdenom","amount":"10"}}}`, + `{"change_admin":{"denom":"factory/creator/subdenom","new_admin_address":"admin"}}`, + `{"set_metadata":{"metadata":{"base":"factory/creator/subdenom"}}}`, + } { + encoded, err := wasmbinding.CustomEncoder(sender, json.RawMessage(msg), wasmvmtypes.MessageInfo{}, wasmtypes.CodeInfo{}) + require.Equal(t, wasmvmtypes.UnsupportedRequest{Kind: "Unknown Sei Wasm Message"}, err, msg) + require.Empty(t, encoded, msg) } - require.Equal(t, expectedMsg, *typedDecodedMsg) } diff --git a/wasmbinding/test/query_test.go b/wasmbinding/test/query_test.go index 214f3b6338..e3a570cc6b 100644 --- a/wasmbinding/test/query_test.go +++ b/wasmbinding/test/query_test.go @@ -16,9 +16,6 @@ import ( epochbinding "github.com/sei-protocol/sei-chain/x/epoch/client/wasm/bindings" epochtypes "github.com/sei-protocol/sei-chain/x/epoch/types" evmwasm "github.com/sei-protocol/sei-chain/x/evm/client/wasm" - tokenfactorywasm "github.com/sei-protocol/sei-chain/x/tokenfactory/client/wasm" - tokenfactorybinding "github.com/sei-protocol/sei-chain/x/tokenfactory/client/wasm/bindings" - tokenfactorytypes "github.com/sei-protocol/sei-chain/x/tokenfactory/types" "github.com/stretchr/testify/require" ) @@ -29,9 +26,8 @@ func SetupWasmbindingTest(t *testing.T) (*app.TestWrapper, func(ctx sdk.Context, testWrapper := app.NewTestWrapper(t, tm, valPub, false) eh := epochwasm.NewEpochWasmQueryHandler(&testWrapper.App.EpochKeeper) - th := tokenfactorywasm.NewTokenFactoryWasmQueryHandler(&testWrapper.App.TokenFactoryKeeper) evmh := evmwasm.NewEVMQueryHandler(&testWrapper.App.EvmKeeper) - qp := wasmbinding.NewQueryPlugin(eh, th, evmh, testWrapper.App.StakingKeeper) + qp := wasmbinding.NewQueryPlugin(eh, evmh, testWrapper.App.StakingKeeper) return testWrapper, wasmbinding.CustomQuerier(qp) } @@ -87,81 +83,17 @@ func TestWasmGetEpoch(t *testing.T) { require.Equal(t, int64(40), epoch.CurrentEpochHeight) } -func TestWasmGetDenomAuthorityMetadata(t *testing.T) { +// TestWasmTokenfactoryRouteIsUnknown requires a query on the tokenfactory route +// to be refused as an unknown Sei query route. +func TestWasmTokenfactoryRouteIsUnknown(t *testing.T) { testWrapper, customQuerier := SetupWasmbindingTest(t) - denom := fmt.Sprintf("factory/%s/test", app.TestUser) - testWrapper.Ctx = testWrapper.Ctx.WithBlockHeight(11).WithBlockTime(time.Unix(3600, 0)) - // Create denom - testWrapper.App.TokenFactoryKeeper.CreateDenom(testWrapper.Ctx, app.TestUser, "test") - authorityMetadata := tokenfactorytypes.DenomAuthorityMetadata{ - Admin: app.TestUser, - } - - // Setup tfk query - req := tokenfactorybinding.SeiTokenFactoryQuery{DenomAuthorityMetadata: &tokenfactorytypes.QueryDenomAuthorityMetadataRequest{Denom: denom}} - queryData, err := json.Marshal(req) - require.NoError(t, err) - query := wasmbinding.SeiQueryWrapper{Route: wasmbinding.TokenFactoryRoute, QueryData: queryData} - - rawQuery, err := json.Marshal(query) - require.NoError(t, err) - - res, err := customQuerier(testWrapper.Ctx, rawQuery) - require.NoError(t, err) - - var parsedRes tokenfactorytypes.QueryDenomAuthorityMetadataResponse - err = json.Unmarshal(res, &parsedRes) - require.NoError(t, err) - require.Equal(t, tokenfactorytypes.QueryDenomAuthorityMetadataResponse{AuthorityMetadata: authorityMetadata}, parsedRes) -} - -func TestWasmGetDenomsFromCreator(t *testing.T) { - testWrapper, customQuerier := SetupWasmbindingTest(t) - - denom1 := fmt.Sprintf("factory/%s/test1", app.TestUser) - denom2 := fmt.Sprintf("factory/%s/test2", app.TestUser) - testWrapper.Ctx = testWrapper.Ctx.WithBlockHeight(11).WithBlockTime(time.Unix(3600, 0)) - - // No denoms created initially - req := tokenfactorybinding.SeiTokenFactoryQuery{DenomsFromCreator: &tokenfactorytypes.QueryDenomsFromCreatorRequest{Creator: app.TestUser}} - queryData, err := json.Marshal(req) + queryData := json.RawMessage(fmt.Sprintf(`{"denoms_from_creator":{"creator":%q}}`, app.TestUser)) + rawQuery, err := json.Marshal(wasmbinding.SeiQueryWrapper{Route: "tokenfactory", QueryData: queryData}) require.NoError(t, err) - query := wasmbinding.SeiQueryWrapper{Route: wasmbinding.TokenFactoryRoute, QueryData: queryData} - - rawQuery, err := json.Marshal(query) - require.NoError(t, err) - - res, err := customQuerier(testWrapper.Ctx, rawQuery) - require.NoError(t, err) - - var parsedRes tokenfactorytypes.QueryDenomsFromCreatorResponse - err = json.Unmarshal(res, &parsedRes) - require.NoError(t, err) - require.Empty(t, parsedRes.Denoms) - - // Add first denom - testWrapper.App.TokenFactoryKeeper.CreateDenom(testWrapper.Ctx, app.TestUser, "test1") - - res, err = customQuerier(testWrapper.Ctx, rawQuery) - require.NoError(t, err) - - var parsedRes2 tokenfactorytypes.QueryDenomsFromCreatorResponse - err = json.Unmarshal(res, &parsedRes2) - require.NoError(t, err) - require.Equal(t, []string{denom1}, parsedRes2.Denoms) - - // Add second denom - testWrapper.App.TokenFactoryKeeper.CreateDenom(testWrapper.Ctx, app.TestUser, "test2") - - res, err = customQuerier(testWrapper.Ctx, rawQuery) - require.NoError(t, err) - - var parsedRes3 tokenfactorytypes.QueryDenomsFromCreatorResponse - err = json.Unmarshal(res, &parsedRes3) - require.NoError(t, err) - require.Equal(t, []string{denom1, denom2}, parsedRes3.Denoms) + _, err = customQuerier(testWrapper.Ctx, rawQuery) + require.Equal(t, wasmvmtypes.UnsupportedRequest{Kind: "Unknown Sei Query Route"}, err) } func MockQueryPlugins() wasmkeeper.QueryPlugins { diff --git a/wasmbinding/wasm.go b/wasmbinding/wasm.go index 8f08f6eedf..c63572ca99 100644 --- a/wasmbinding/wasm.go +++ b/wasmbinding/wasm.go @@ -11,13 +11,10 @@ import ( epochkeeper "github.com/sei-protocol/sei-chain/x/epoch/keeper" evmwasm "github.com/sei-protocol/sei-chain/x/evm/client/wasm" evmkeeper "github.com/sei-protocol/sei-chain/x/evm/keeper" - tokenfactorywasm "github.com/sei-protocol/sei-chain/x/tokenfactory/client/wasm" - tokenfactorykeeper "github.com/sei-protocol/sei-chain/x/tokenfactory/keeper" ) func RegisterCustomPlugins( epoch *epochkeeper.Keeper, - tokenfactory *tokenfactorykeeper.Keeper, _ *authkeeper.AccountKeeper, router wasmkeeper.MessageRouter, bankKeeper wasmtypes.Burner, @@ -26,9 +23,8 @@ func RegisterCustomPlugins( stakingKeeper stakingkeeper.Keeper, ) []wasmkeeper.Option { epochHandler := epochwasm.NewEpochWasmQueryHandler(epoch) - tokenfactoryHandler := tokenfactorywasm.NewTokenFactoryWasmQueryHandler(tokenfactory) evmHandler := evmwasm.NewEVMQueryHandler(evmKeeper) - wasmQueryPlugin := NewQueryPlugin(epochHandler, tokenfactoryHandler, evmHandler, stakingKeeper) + wasmQueryPlugin := NewQueryPlugin(epochHandler, evmHandler, stakingKeeper) queryPluginOpt := wasmkeeper.WithQueryPlugins(&wasmkeeper.QueryPlugins{ Custom: CustomQuerier(wasmQueryPlugin), diff --git a/x/tokenfactory/README.md b/x/tokenfactory/README.md deleted file mode 100644 index c071661b29..0000000000 --- a/x/tokenfactory/README.md +++ /dev/null @@ -1,181 +0,0 @@ -# Token Factory - -The tokenfactory module allows any account to create a new token with -the name `factory/{creator address}/{subdenom}`. Because tokens are -namespaced by creator address, this allows token minting to be -permissionless, due to not needing to resolve name collisions. A single -account can create multiple denoms, by providing a unique subdenom for each -created denom. Once a denom is created, the original creator is given -"admin" privileges over the asset. This allows them to: - -- Mint their denom to any account -- Burn their denom from any account -- Create a transfer of their denom between any two accounts -- Change the admin. In the future, more admin capabilities may be added. Admins - can choose to share admin privileges with other accounts using the authz - module. The `ChangeAdmin` functionality, allows changing the master admin - account, or even setting it to `""`, meaning no account has admin privileges - of the asset. - -## Messages - -### CreateDenom - -Creates a denom of `factory/{creator address}/{subdenom}` given the denom creator -address and the subdenom. Subdenoms can contain `[a-zA-Z0-9./]`. - -```go -message MsgCreateDenom { - string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; - string subdenom = 2 [ (gogoproto.moretags) = "yaml:\"subdenom\"" ]; -} -``` - -**State Modifications:** - -- Set `DenomMetaData` via bank keeper. -- Set `AuthorityMetadata` for the given denom to store the admin for the created - denom `factory/{creator address}/{subdenom}`. Admin is automatically set as the - Msg sender. -- Add denom to the `CreatorPrefixStore`, where a state of denoms created per - creator is kept. - -### Mint - -Minting of a specific denom is only allowed for the current admin. -Note, the current admin is defaulted to the creator of the denom. - -```protobuf -message MsgMint { - string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; - cosmos.base.v1beta1.Coin amount = 2 [ - (gogoproto.moretags) = "yaml:\"amount\"", - (gogoproto.nullable) = false - ]; -} -``` - -**State Modifications:** - -- Safety check the following - - Check that the denom minting is created via `tokenfactory` module - - Check that the sender of the message is the admin of the denom -- Mint designated amount of tokens for the denom via `bank` module - -### Burn - -Burning of a specific denom is only allowed for the current admin. -Note, the current admin is defaulted to the creator of the denom. - -```protobuf -message MsgBurn { - string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; - cosmos.base.v1beta1.Coin amount = 2 [ - (gogoproto.moretags) = "yaml:\"amount\"", - (gogoproto.nullable) = false - ]; -} -``` - -**State Modifications:** - -- Safety check the following - - Check that the denom is created via `tokenfactory` module - - Check that the sender of the message is the admin of the denom -- Burn designated amount of tokens for the denom via `bank` module - -### ChangeAdmin - -Change the admin of a denom. Note, this is only allowed to be called by the current admin of the denom. - -```protobuf -message MsgChangeAdmin { - string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; - string denom = 2 [ (gogoproto.moretags) = "yaml:\"denom\"" ]; - string newAdmin = 3 [ (gogoproto.moretags) = "yaml:\"new_admin\"" ]; -} -``` - -**State Modifications:** - -- Check that sender of the message is the admin of denom -- Modify `AuthorityMetadata` state entry to change the admin of the denom - -## Tokenfactory Denom Restrictions - -Tokenfactory denoms are of form `factory/{creator address}/{subdenom}`. - -- The Max Subdenom length is 44 characters -- The Max Creator length is 75 characters -- All tokenfactory denoms will begin with `factory` - -Please reference the Appendix for more details on the derivation of these limits. - -# Examples -To create a new token, use the create-denom command from the tokenfactory module. The following example uses the address sei166vhptur29s3gw5qr6dm30s06gej6pr4n6qc4l from mylocalwallet as the default admin for the new token. - -## Creating a token -To create a new token we can use the create-denom command. - -```sh -seid tx tokenfactory create-denom ufoo --from mylocalwallet -``` - -## Mint a new token -Once a new token is created, it can be minted using the mint command in the tokenfactory module. Note that the complete tokenfactory address, in the format of factory/{creator address}/{subdenom}, must be used to mint the token. - -```sh -seid tx tokenfactory mint 100000000000factory/sei166vhptur29s3gw5qr6dm30s06gej6pr4n6qc4l/ufoo --from mylocalwallet -``` - -## Checking Token metadata -To view a token's metadata, use the denom-metadata command in the bank module. The following example queries the metadata for the token factory/sei166vhptur29s3gw5qr6dm30s06gej6pr4n6qc4l/ufoo: - -```sh -seid query bank denom-metadata --denom factory/sei166vhptur29s3gw5qr6dm30s06gej6pr4n6qc4l/ufoo -``` - -## Check the tokens created by an account -To see a list of tokens created by a specific account, use the denoms-from-creator command in the tokenfactory module. The following example shows tokens created by the account sei166vhptur29s3gw5qr6dm30s06gej6pr4n6qc4l: - -```sh -seid query tokenfactory denoms-from-creator sei166vhptur29s3gw5qr6dm30s06gej6pr4n6qc4ls -``` - -## Appendix: Expectations from the Chain - -As mentioned above, the chain's bech32 prefix for addresses can be at most 16 characters long. - -This comes from denoms having a 128 byte maximum length, enforced from the SDK, -and us setting longest_subdenom to be 44 bytes. - -A token factory token's denom is: `factory/{creator address}/{subdenom}` - -Splitting up into sub-components, this has: - -- `len(factory) = 7` -- `2 * len("/") = 2` -- `len(longest_subdenom)` -- `len(creator_address) = len(bech32(longest_addr_length, chain_addr_prefix))`. - -Longest addr length at the moment is `32 bytes`. Due to SDK error correction -settings, this means `len(bech32(32, chain_addr_prefix)) = len(chain_addr_prefix) + 1 + 58`. -Adding this all, we have a total length constraint of `128 = 7 + 2 + len(longest_subdenom) + len(longest_chain_addr_prefix) + 1 + 58`. -Therefore `len(longest_subdenom) + len(longest_chain_addr_prefix) = 128 - (7 + 2 + 1 + 58) = 60`. - -Considerations for how we split these 60 bytes between maxes from -longest_subdenom and longest_chain_addr_prefix: - -- Per [BIP-0173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32) - the technically longest HRP for a 32 byte address ('data field') is 31 bytes. - (Comes from encode(data) = 59 bytes, and max length = 90 bytes) -- subdenom should be at least 32 bytes so hashes can go into it -- longer subdenoms are very helpful for creating human readable denoms -- chain addresses should prefer being smaller. The longest HRP in cosmos to date is 11 bytes. (`persistence`) - -For explicitness, its currently set to `len(longest_subdenom) = 44` and `len(longest_chain_addr_prefix) = 16`. - -Please note, if the SDK increases the maximum length of a denom from 128 bytes, -these caps should increase. - -So please don't make code rely on these max lengths for parsing. diff --git a/x/tokenfactory/client/cli/query.go b/x/tokenfactory/client/cli/query.go deleted file mode 100644 index 85f41d4300..0000000000 --- a/x/tokenfactory/client/cli/query.go +++ /dev/null @@ -1,129 +0,0 @@ -package cli - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/sei-protocol/sei-chain/sei-cosmos/client" - "github.com/sei-protocol/sei-chain/sei-cosmos/client/flags" - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -// GetQueryCmd returns the cli query commands for this module -func GetQueryCmd() *cobra.Command { - // Group tokenfactory queries under a subcommand - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - cmd.AddCommand( - GetParams(), - GetCmdDenomAuthorityMetadata(), - GetCmdDenomsFromCreator(), - ) - - return cmd -} - -// GetParams returns the params for the module -func GetParams() *cobra.Command { - cmd := &cobra.Command{ - Use: "params [flags]", - Short: "Get the params for the x/tokenfactory module", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - - res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} - -// GetCmdDenomAuthorityMetadata returns the authority metadata for a queried denom -func GetCmdDenomAuthorityMetadata() *cobra.Command { - cmd := &cobra.Command{ - Use: "denom-authority-metadata [denom] [flags]", - Short: "Get the authority metadata for a specific denom", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - - res, err := queryClient.DenomAuthorityMetadata(cmd.Context(), &types.QueryDenomAuthorityMetadataRequest{ - Denom: args[0], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} - -// GetCmdDenomsFromCreator a command to get a list of all tokens created by a specific creator address -func GetCmdDenomsFromCreator() *cobra.Command { - cmd := &cobra.Command{ - Use: "denoms-from-creator [creator address] [flags]", - Short: "Returns a list of all tokens created by a specific creator address", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - - if _, err := sdk.AccAddressFromBech32(args[0]); err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - res, err := queryClient.DenomsFromCreator(cmd.Context(), &types.QueryDenomsFromCreatorRequest{ - Creator: args[0], - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "denoms-from-creator") - - return cmd -} diff --git a/x/tokenfactory/client/cli/tx.go b/x/tokenfactory/client/cli/tx.go deleted file mode 100644 index 9c01e5fec0..0000000000 --- a/x/tokenfactory/client/cli/tx.go +++ /dev/null @@ -1,357 +0,0 @@ -package cli - -import ( - "context" - "encoding/json" - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/ethereum/go-ethereum/common" - - "github.com/spf13/cobra" - - "github.com/sei-protocol/sei-chain/sei-cosmos/client" - "github.com/sei-protocol/sei-chain/sei-cosmos/client/flags" - "github.com/sei-protocol/sei-chain/sei-cosmos/client/tx" - "github.com/sei-protocol/sei-chain/sei-cosmos/codec" - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - evmtypes "github.com/sei-protocol/sei-chain/x/evm/types" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -const ( - FlagAllowList = "allow-list" - FlagAllowListDescription = "Path to the allow list JSON file with an array of addresses " + - "that are allowed to send/receive the token. The file should have the following format: {\"addresses\": " + - "[\"addr1\", \"addr2\"]}, where addr1 and addr2 are bech32 Sei native addresses or EVM addresses." -) - -// GetTxCmd returns the transaction commands for this module -func GetTxCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - cmd.AddCommand( - NewCreateDenomCmd(), - NewUpdateDenomCmd(), - NewMintCmd(), - NewBurnCmd(), - NewChangeAdminCmd(), - NewSetDenomMetadataCmd(), - ) - - return cmd -} - -// NewCreateDenomCmd broadcast MsgCreateDenom -func NewCreateDenomCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "create-denom [subdenom] [flags]", - Short: "create a new denom from an account", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - queryClientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := evmtypes.NewQueryClient(queryClientCtx) - - allowListFilePath, err := cmd.Flags().GetString(FlagAllowList) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - msg := types.NewMsgCreateDenom( - clientCtx.GetFromAddress().String(), - args[0], - ) - - // only parse allow list if it is provided - if allowListFilePath != "" { - // Parse the allow list - allowList, err := ParseAllowListJSON(allowListFilePath, queryClient) - if err != nil { - return err - } - msg.AllowList = &allowList - } - - return tx.GenerateOrBroadcastTxWithFactory(cmd.Context(), clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - cmd.Flags().String(FlagAllowList, "", FlagAllowListDescription) - return cmd -} - -// NewUpdateDenomCmd broadcast MsgUpdateDenom -func NewUpdateDenomCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "update-denom [denom] [flags]", - Short: "update a denom from an account", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - queryClientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := evmtypes.NewQueryClient(queryClientCtx) - - allowListFilePath, err := cmd.Flags().GetString(FlagAllowList) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - // Fail if allow list is not provided as this is the only feature that can be updated for now - if allowListFilePath == "" { - return fmt.Errorf("allow list file path is required") - } - - allowList, err := ParseAllowListJSON(allowListFilePath, queryClient) - if err != nil { - return err - } - - msg := types.NewMsgUpdateDenom( - clientCtx.GetFromAddress().String(), - args[0], - &allowList, - ) - - return tx.GenerateOrBroadcastTxWithFactory(cmd.Context(), clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - cmd.Flags().String(FlagAllowList, "", FlagAllowListDescription) - return cmd -} - -// NewMintCmd broadcast MsgMint -func NewMintCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "mint [amount] [flags]", - Short: "Mint a denom to an address. Must have admin authority to do so.", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - amount, err := sdk.ParseCoinNormalized(args[0]) - if err != nil { - return err - } - - msg := types.NewMsgMint( - clientCtx.GetFromAddress().String(), - amount, - ) - - return tx.GenerateOrBroadcastTxWithFactory(cmd.Context(), clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - return cmd -} - -// NewBurnCmd broadcast MsgBurn -func NewBurnCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "burn [amount] [flags]", - Short: "Burn tokens from an address. Must have admin authority to do so.", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - amount, err := sdk.ParseCoinNormalized(args[0]) - if err != nil { - return err - } - - msg := types.NewMsgBurn( - clientCtx.GetFromAddress().String(), - amount, - ) - - return tx.GenerateOrBroadcastTxWithFactory(cmd.Context(), clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - return cmd -} - -// NewChangeAdminCmd broadcast MsgChangeAdmin -func NewChangeAdminCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "change-admin [denom] [new-admin-address] [flags]", - Short: "Changes the admin address for a factory-created denom. Must have admin authority to do so.", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - msg := types.NewMsgChangeAdmin( - clientCtx.GetFromAddress().String(), - args[0], - args[1], - ) - - return tx.GenerateOrBroadcastTxWithFactory(cmd.Context(), clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - return cmd -} - -func NewSetDenomMetadataCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "set-denom-metadata [metadata-file] [flags]", - Short: "Set metadata for a factory-created denom. Must have admin authority to do so.", - Long: strings.TrimSpace( - ` -Example: -$ seid tx tokenfactory set-denom-metadata --from= - -Where metadata.json contains: - -{ - "description": "Update token metadata", - "denom_units": [ - { - "denom": "doge1", - "exponent": 6, - "aliases": ["d", "o", "g"] - }, - { - "denom": "doge2", - "exponent": 3, - "aliases": ["d", "o", "g"] - } - ], - "base": "doge", - "display": "DOGE", - "name": "dogecoin", - "symbol": "DOGE" -}`), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - metadata, err := ParseMetadataJSON(clientCtx.LegacyAmino, args[0]) - if err != nil { - return err - } - - msg := types.NewMsgSetDenomMetadata( - clientCtx.GetFromAddress().String(), - metadata, - ) - - return tx.GenerateOrBroadcastTxWithFactory(cmd.Context(), clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - return cmd -} - -func ParseMetadataJSON(cdc *codec.LegacyAmino, metadataFile string) (banktypes.Metadata, error) { - proposal := banktypes.Metadata{} - - contents, err := os.ReadFile(filepath.Clean(metadataFile)) - if err != nil { - return proposal, err - } - - if err := cdc.UnmarshalAsJSON(contents, &proposal); err != nil { - return proposal, err - } - - return proposal, nil -} - -func ParseAllowListJSON(allowListFile string, queryClient evmtypes.QueryClient) (banktypes.AllowList, error) { - allowList := banktypes.AllowList{} - - file, err := os.Open(filepath.Clean(allowListFile)) - if err != nil { - return allowList, err - } - defer func() { _ = file.Close() }() - - decoder := json.NewDecoder(file) - if err := decoder.Decode(&allowList); err != nil { - return allowList, err - } - - addressMap := make(map[string]struct{}) - uniqueAddresses := []string{} - for _, addr := range allowList.Addresses { - if _, exists := addressMap[addr]; exists { - continue // Skip duplicate addresses - } - addressMap[addr] = struct{}{} - - if common.IsHexAddress(addr) { - res, err := queryClient.SeiAddressByEVMAddress(context.Background(), &evmtypes.QuerySeiAddressByEVMAddressRequest{EvmAddress: addr}) - if res != nil && !res.Associated { - return allowList, fmt.Errorf("address %s is not associated", addr) - } - if err != nil { - return allowList, err - } - uniqueAddresses = append(uniqueAddresses, res.SeiAddress) - continue - } - if _, err := sdk.AccAddressFromBech32(addr); err != nil { - return allowList, fmt.Errorf("invalid address %s: %w", addr, err) - } - uniqueAddresses = append(uniqueAddresses, addr) - } - - allowList.Addresses = uniqueAddresses - return allowList, nil -} diff --git a/x/tokenfactory/client/cli/tx_test.go b/x/tokenfactory/client/cli/tx_test.go deleted file mode 100644 index 9b242dc812..0000000000 --- a/x/tokenfactory/client/cli/tx_test.go +++ /dev/null @@ -1,294 +0,0 @@ -package cli - -import ( - "bytes" - "context" - "fmt" - "os" - "testing" - - "github.com/sei-protocol/sei-chain/sei-cosmos/client" - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - "google.golang.org/grpc" - - "github.com/sei-protocol/sei-chain/sei-cosmos/codec" - "github.com/sei-protocol/sei-chain/sei-cosmos/testutil" - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - evmtypes "github.com/sei-protocol/sei-chain/x/evm/types" - "github.com/stretchr/testify/require" -) - -func TestParseMetadata(t *testing.T) { - cdc := codec.NewLegacyAmino() - okJSON := testutil.WriteToNewTempFile(t, ` -{ - "description": "Update token metadata", - "denom_units": [ - { - "denom": "doge1", - "exponent": 6, - "aliases": ["d", "o", "g"] - }, - { - "denom": "doge2", - "exponent": 3, - "aliases": ["d", "o", "g"] - } - ], - "base": "doge", - "display": "DOGE", - "name": "dogecoin", - "symbol": "DOGE" -} -`) - metadata, err := ParseMetadataJSON(cdc, okJSON.Name()) - require.NoError(t, err) - - require.Equal(t, banktypes.Metadata{ - Description: "Update token metadata", - DenomUnits: []*banktypes.DenomUnit{{ - Denom: "doge1", - Exponent: 6, - Aliases: []string{"d", "o", "g"}, - }, { - Denom: "doge2", - Exponent: 3, - Aliases: []string{"d", "o", "g"}, - }}, - Base: "doge", - Display: "DOGE", - Name: "dogecoin", - Symbol: "DOGE", - }, metadata) -} - -type MockQueryClient struct { - evmtypes.QueryClient -} - -func (m *MockQueryClient) SeiAddressByEVMAddress(ctx context.Context, in *evmtypes.QuerySeiAddressByEVMAddressRequest, opts ...grpc.CallOption) (*evmtypes.QuerySeiAddressByEVMAddressResponse, error) { - if in.EvmAddress == "0x0CF3Bb7Da9fea6a881987A5018740500C7d4BAaE" { - return &evmtypes.QuerySeiAddressByEVMAddressResponse{SeiAddress: "", Associated: false}, nil - } - return &evmtypes.QuerySeiAddressByEVMAddressResponse{SeiAddress: "sei1u8j4gaxyzhg39dk848q5w9h53tgggpcx74m762", Associated: true}, nil -} - -type MockErrorQueryClient struct { - evmtypes.QueryClient -} - -func (m *MockErrorQueryClient) SeiAddressByEVMAddress(ctx context.Context, in *evmtypes.QuerySeiAddressByEVMAddressRequest, opts ...grpc.CallOption) (*evmtypes.QuerySeiAddressByEVMAddressResponse, error) { - return nil, fmt.Errorf("address is not associated") -} - -func Test_ParseAllowListJSON(t *testing.T) { - mockQueryClient := &MockQueryClient{} - - seiAddr1 := sdk.AccAddress("sei1_______________").String() - seiAddr2 := sdk.AccAddress("sei2_______________").String() - evmAddr := "0x5c71b5577B9223d39ae0B7Dcb3f1BC8e1aC81f3e" - notAssociatedEvmAddr := "0x0CF3Bb7Da9fea6a881987A5018740500C7d4BAaE" - convertedSeiAddr := "sei1u8j4gaxyzhg39dk848q5w9h53tgggpcx74m762" - - tests := []struct { - name string - json string - want banktypes.AllowList - wantErr string - errMock bool - }{ - { - name: "valid allow list with Sei addresses", - json: fmt.Sprintf(`{"addresses": ["%s", "%s"]}`, seiAddr1, seiAddr2), - want: banktypes.AllowList{Addresses: []string{seiAddr1, seiAddr2}}, - }, - { - name: "valid allow list with Sei and EVM addresses", - json: fmt.Sprintf(`{"addresses": ["%s", "%s", "%s"]}`, seiAddr1, seiAddr2, evmAddr), - want: banktypes.AllowList{Addresses: []string{seiAddr1, seiAddr2, convertedSeiAddr}}, - }, - { - name: "invalid JSON", - json: `{[}`, - wantErr: "invalid character '[' looking for beginning of object key string", - }, - { - name: "invalid Sei address", - json: `{"addresses": ["invalid_sei_address"]}`, - wantErr: "invalid address invalid_sei_address: decoding bech32 failed: invalid separator index -1", - }, - { - name: "invalid EVM address", - json: `{"addresses": ["0xinvalid_evm_address"]}`, - wantErr: "invalid address 0xinvalid_evm_address: decoding bech32 failed: invalid separator index -1", - }, - { - name: "EVM address error on getting Sei address", - json: fmt.Sprintf(`{"addresses": ["%s"]}`, evmAddr), - wantErr: "address is not associated", - errMock: true, - }, - { - name: "EVM address not associated", - json: fmt.Sprintf(`{"addresses": ["%s"]}`, notAssociatedEvmAddr), - wantErr: "address 0x0CF3Bb7Da9fea6a881987A5018740500C7d4BAaE is not associated", - }, - { - name: "empty allow list", - json: `{"addresses": []}`, - want: banktypes.AllowList{Addresses: []string{}}, - }, - { - name: "duplicate addresses", - json: fmt.Sprintf(`{"addresses": ["%s", "%s", "%s"]}`, seiAddr1, seiAddr1, seiAddr2), - want: banktypes.AllowList{Addresses: []string{seiAddr1, seiAddr2}}, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - - tempFile := testutil.WriteToNewTempFile(t, tt.json) - defer os.Remove(tempFile.Name()) - - var m evmtypes.QueryClient - m = mockQueryClient - if tt.errMock { - m = &MockErrorQueryClient{} - } - - got, err := ParseAllowListJSON(tempFile.Name(), m) - if tt.wantErr != "" { - require.Error(t, err) - require.Equal(t, tt.wantErr, err.Error()) - } else { - require.NoError(t, err) - require.Equal(t, tt.want, got) - } - }) - } - - t.Run("non-existent file", func(t *testing.T) { - _, err := ParseAllowListJSON("non_existent_file.json", mockQueryClient) - require.Error(t, err) - require.Contains(t, err.Error(), "no such file or directory") - }) -} - -func TestNewCreateDenomCmd_AllowList(t *testing.T) { - // Setup codec and client context - cdc := codec.NewLegacyAmino() - clientCtx := client.Context{}.WithLegacyAmino(cdc) - - // Create a temporary command to test - cmd := NewCreateDenomCmd() - cmd.SetContext(context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)) - - // Create a temporary allow list JSON file with invalid content - jsonInvalidFile := testutil.WriteToNewTempFile(t, `{[}`) - - // Define test cases - testCases := []struct { - name string - args []string - flags []string - expectErr bool - expectedError string - }{ - { - name: "command fails with invalid allow list", - args: []string{"subdenom"}, - flags: []string{"--allow-list", jsonInvalidFile.Name()}, - expectErr: true, - expectedError: "invalid character '[' looking for beginning of object key string", - }, - { - name: "invalid: non-existent allow list file", - args: []string{"subdenom"}, - flags: []string{"--allow-list", "non_existent_file.json"}, - expectErr: true, - expectedError: "open non_existent_file.json: no such file or directory", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - // Set command arguments and flags - cmd.SetArgs(append(tc.args, tc.flags...)) - - // Capture output - out := &bytes.Buffer{} - cmd.SetOut(out) - - // Execute command - err := cmd.Execute() - - // Check for expected errors - if tc.expectErr { - require.Error(t, err) - require.Contains(t, err.Error(), tc.expectedError) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestNewUpdateDenomCmd_AllowList(t *testing.T) { - // Setup codec and client context - cdc := codec.NewLegacyAmino() - clientCtx := client.Context{}.WithLegacyAmino(cdc) - - // Create a temporary command to test - cmd := NewUpdateDenomCmd() - cmd.SetContext(context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)) - - // Create a temporary allow list JSON file with invalid content - jsonInvalidFile := testutil.WriteToNewTempFile(t, `{[}`) - - // Define test cases - testCases := []struct { - name string - args []string - flags []string - expectErr bool - expectedError string - }{ - { - name: "command fails with invalid allow list", - args: []string{"subdenom"}, - flags: []string{"--allow-list", jsonInvalidFile.Name()}, - expectErr: true, - expectedError: "invalid character '[' looking for beginning of object key string", - }, - { - name: "invalid: non-existent allow list file", - args: []string{"subdenom"}, - flags: []string{"--allow-list", "non_existent_file.json"}, - expectErr: true, - expectedError: "open non_existent_file.json: no such file or directory", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - // Set command arguments and flags - cmd.SetArgs(append(tc.args, tc.flags...)) - - // Capture output - out := &bytes.Buffer{} - cmd.SetOut(out) - - // Execute command - err := cmd.Execute() - - // Check for expected errors - if tc.expectErr { - require.Error(t, err) - require.Contains(t, err.Error(), tc.expectedError) - } else { - require.NoError(t, err) - } - }) - } -} diff --git a/x/tokenfactory/client/wasm/bindings/queries.go b/x/tokenfactory/client/wasm/bindings/queries.go deleted file mode 100644 index 65809891a1..0000000000 --- a/x/tokenfactory/client/wasm/bindings/queries.go +++ /dev/null @@ -1,10 +0,0 @@ -package bindings - -import "github.com/sei-protocol/sei-chain/x/tokenfactory/types" - -type SeiTokenFactoryQuery struct { - // queries the tokenfactory authority metadata - DenomAuthorityMetadata *types.QueryDenomAuthorityMetadataRequest `json:"denom_authority_metadata,omitempty"` - // queries the tokenfactory denoms from a creator - DenomsFromCreator *types.QueryDenomsFromCreatorRequest `json:"denoms_from_creator,omitempty"` -} diff --git a/x/tokenfactory/client/wasm/encoder.go b/x/tokenfactory/client/wasm/encoder.go deleted file mode 100644 index 2ace8f7a80..0000000000 --- a/x/tokenfactory/client/wasm/encoder.go +++ /dev/null @@ -1,70 +0,0 @@ -package wasm - -import ( - "encoding/json" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - "github.com/sei-protocol/sei-chain/wasmbinding/bindings" - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -func EncodeTokenFactoryCreateDenom(rawMsg json.RawMessage, sender sdk.AccAddress) ([]sdk.Msg, error) { - encodedCreateDenomMsg := bindings.CreateDenom{} - if err := json.Unmarshal(rawMsg, &encodedCreateDenomMsg); err != nil { - return []sdk.Msg{}, types.ErrEncodeTokenFactoryCreateDenom - } - createDenomMsg := types.MsgCreateDenom{ - Sender: sender.String(), - Subdenom: encodedCreateDenomMsg.Subdenom, - } - return []sdk.Msg{&createDenomMsg}, nil -} - -func EncodeTokenFactoryMint(rawMsg json.RawMessage, sender sdk.AccAddress) ([]sdk.Msg, error) { - encodedMintMsg := bindings.MintTokens{} - if err := json.Unmarshal(rawMsg, &encodedMintMsg); err != nil { - return []sdk.Msg{}, types.ErrEncodeTokenFactoryMint - } - mintMsg := types.MsgMint{ - Sender: sender.String(), - Amount: encodedMintMsg.Amount, - } - return []sdk.Msg{&mintMsg}, nil -} - -func EncodeTokenFactoryBurn(rawMsg json.RawMessage, sender sdk.AccAddress) ([]sdk.Msg, error) { - encodedBurnMsg := bindings.BurnTokens{} - if err := json.Unmarshal(rawMsg, &encodedBurnMsg); err != nil { - return []sdk.Msg{}, types.ErrEncodeTokenFactoryBurn - } - burnMsg := types.MsgBurn{ - Sender: sender.String(), - Amount: encodedBurnMsg.Amount, - } - return []sdk.Msg{&burnMsg}, nil -} - -func EncodeTokenFactoryChangeAdmin(rawMsg json.RawMessage, sender sdk.AccAddress) ([]sdk.Msg, error) { - encodedChangeAdminMsg := bindings.ChangeAdmin{} - if err := json.Unmarshal(rawMsg, &encodedChangeAdminMsg); err != nil { - return []sdk.Msg{}, types.ErrEncodeTokenFactoryChangeAdmin - } - changeAdminMsg := types.MsgChangeAdmin{ - Sender: sender.String(), - Denom: encodedChangeAdminMsg.Denom, - NewAdmin: encodedChangeAdminMsg.NewAdminAddress, - } - return []sdk.Msg{&changeAdminMsg}, nil -} - -func EncodeTokenFactorySetMetadata(rawMsg json.RawMessage, sender sdk.AccAddress) ([]sdk.Msg, error) { - encodedSetMetadataMsg := bindings.SetMetadata{} - if err := json.Unmarshal(rawMsg, &encodedSetMetadataMsg); err != nil { - return []sdk.Msg{}, types.ErrEncodeTokenFactorySetMetadata - } - setMetadataMsg := types.MsgSetDenomMetadata{ - Sender: sender.String(), - Metadata: encodedSetMetadataMsg.Metadata, - } - return []sdk.Msg{&setMetadataMsg}, nil -} diff --git a/x/tokenfactory/client/wasm/query.go b/x/tokenfactory/client/wasm/query.go deleted file mode 100644 index e235eba806..0000000000 --- a/x/tokenfactory/client/wasm/query.go +++ /dev/null @@ -1,27 +0,0 @@ -package wasm - -import ( - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - tokenfactorykeeper "github.com/sei-protocol/sei-chain/x/tokenfactory/keeper" - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -type TokenFactoryWasmQueryHandler struct { - tokenfactoryKeeper tokenfactorykeeper.Keeper -} - -func NewTokenFactoryWasmQueryHandler(keeper *tokenfactorykeeper.Keeper) *TokenFactoryWasmQueryHandler { - return &TokenFactoryWasmQueryHandler{ - tokenfactoryKeeper: *keeper, - } -} - -func (handler TokenFactoryWasmQueryHandler) GetDenomAuthorityMetadata(ctx sdk.Context, req *types.QueryDenomAuthorityMetadataRequest) (*types.QueryDenomAuthorityMetadataResponse, error) { - c := sdk.WrapSDKContext(ctx) - return handler.tokenfactoryKeeper.DenomAuthorityMetadata(c, req) -} - -func (handler TokenFactoryWasmQueryHandler) GetDenomsFromCreator(ctx sdk.Context, req *types.QueryDenomsFromCreatorRequest) (*types.QueryDenomsFromCreatorResponse, error) { - denoms := handler.tokenfactoryKeeper.GetAllDenomsFromCreator(ctx, req.Creator) - return &types.QueryDenomsFromCreatorResponse{Denoms: denoms}, nil -} diff --git a/x/tokenfactory/keeper/admins.go b/x/tokenfactory/keeper/admins.go deleted file mode 100644 index 5a9157b90c..0000000000 --- a/x/tokenfactory/keeper/admins.go +++ /dev/null @@ -1,49 +0,0 @@ -package keeper - -import ( - "github.com/gogo/protobuf/proto" - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -// GetAuthorityMetadata returns the authority metadata for a specific denom -func (k Keeper) GetAuthorityMetadata(ctx sdk.Context, denom string) (types.DenomAuthorityMetadata, error) { - bz := k.GetDenomPrefixStore(ctx, denom).Get([]byte(types.DenomAuthorityMetadataKey)) - - metadata := types.DenomAuthorityMetadata{} - err := proto.Unmarshal(bz, &metadata) - if err != nil { - return types.DenomAuthorityMetadata{}, err - } - return metadata, nil -} - -// setAuthorityMetadata stores authority metadata for a specific denom -func (k Keeper) setAuthorityMetadata(ctx sdk.Context, denom string, metadata types.DenomAuthorityMetadata) error { - err := metadata.Validate() - if err != nil { - return err - } - - store := k.GetDenomPrefixStore(ctx, denom) - - bz, err := proto.Marshal(&metadata) - if err != nil { - return err - } - - store.Set([]byte(types.DenomAuthorityMetadataKey), bz) - return nil -} - -func (k Keeper) setAdmin(ctx sdk.Context, denom string, admin string) error { - metadata, err := k.GetAuthorityMetadata(ctx, denom) - if err != nil { - return err - } - - metadata.Admin = admin - - return k.setAuthorityMetadata(ctx, denom, metadata) -} diff --git a/x/tokenfactory/keeper/admins_test.go b/x/tokenfactory/keeper/admins_test.go deleted file mode 100644 index 74a22a994d..0000000000 --- a/x/tokenfactory/keeper/admins_test.go +++ /dev/null @@ -1,296 +0,0 @@ -package keeper_test - -import ( - "fmt" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -func (suite *KeeperTestSuite) TestAdminMsgs() { - addr0bal := int64(0) - addr1bal := int64(0) - - suite.CreateDefaultDenom() - // Make sure that the admin is set correctly - queryRes, err := suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ - Denom: suite.defaultDenom, - }) - suite.Require().NoError(err) - suite.Require().Equal(suite.TestAccs[0].String(), queryRes.AuthorityMetadata.Admin) - - // Test minting to admins own account - _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 10))) - - addr0bal += 10 - suite.Require().NoError(err) - suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom).Amount.Int64() == addr0bal, suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom)) - - // Test burning from own account - _, err = suite.msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 5))) - - addr0bal -= 5 - suite.Require().NoError(err) - suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom).Amount.Int64() == addr1bal) - - // Test Change Admin - _, err = suite.msgServer.ChangeAdmin(sdk.WrapSDKContext(suite.Ctx), types.NewMsgChangeAdmin(suite.TestAccs[0].String(), suite.defaultDenom, suite.TestAccs[1].String())) - suite.Require().NoError(err) - queryRes, err = suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ - Denom: suite.defaultDenom, - }) - suite.Require().NoError(err) - suite.Require().Equal(suite.TestAccs[1].String(), queryRes.AuthorityMetadata.Admin) - - // Make sure old admin can no longer do actions - _, err = suite.msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 5))) - - suite.Require().Error(err) - - // Make sure the new admin works - _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[1].String(), sdk.NewInt64Coin(suite.defaultDenom, 5))) - - addr1bal += 5 - suite.Require().NoError(err) - suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[1], suite.defaultDenom).Amount.Int64() == addr1bal) - - // Try setting admin to empty - _, err = suite.msgServer.ChangeAdmin(sdk.WrapSDKContext(suite.Ctx), types.NewMsgChangeAdmin(suite.TestAccs[1].String(), suite.defaultDenom, "")) - - suite.Require().NoError(err) - queryRes, err = suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ - Denom: suite.defaultDenom, - }) - suite.Require().NoError(err) - suite.Require().Equal("", queryRes.AuthorityMetadata.Admin) -} - -func (suite *KeeperTestSuite) TestChangeAdminDenom() { - for _, tc := range []struct { - desc string - msgChangeAdmin func(denom string) *types.MsgChangeAdmin - expectedChangeAdminPass bool - expectedAdminIndex int - msgMint func(denom string) *types.MsgMint - expectedMintPass bool - }{ - { - desc: "creator admin can't mint after setting to '' ", - msgChangeAdmin: func(denom string) *types.MsgChangeAdmin { - return types.NewMsgChangeAdmin(suite.TestAccs[0].String(), denom, "") - }, - expectedChangeAdminPass: true, - expectedAdminIndex: -1, - msgMint: func(denom string) *types.MsgMint { - return types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(denom, 5)) - }, - expectedMintPass: false, - }, - { - desc: "non-admins can't change the existing admin", - msgChangeAdmin: func(denom string) *types.MsgChangeAdmin { - return types.NewMsgChangeAdmin(suite.TestAccs[1].String(), denom, suite.TestAccs[2].String()) - }, - expectedChangeAdminPass: false, - expectedAdminIndex: 0, - }, - { - desc: "change to same admin should fail", - msgChangeAdmin: func(denom string) *types.MsgChangeAdmin { - return types.NewMsgChangeAdmin(suite.TestAccs[0].String(), denom, suite.TestAccs[0].String()) - }, - expectedChangeAdminPass: false, - expectedAdminIndex: 0, - }, - { - desc: "success change admin", - msgChangeAdmin: func(denom string) *types.MsgChangeAdmin { - return types.NewMsgChangeAdmin(suite.TestAccs[0].String(), denom, suite.TestAccs[1].String()) - }, - expectedAdminIndex: 1, - expectedChangeAdminPass: true, - msgMint: func(denom string) *types.MsgMint { - return types.NewMsgMint(suite.TestAccs[1].String(), sdk.NewInt64Coin(denom, 5)) - }, - expectedMintPass: true, - }, - } { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { - // setup test - suite.SetupTest() - - // Create a denom and mint - res, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "bitcoin")) - suite.Require().NoError(err) - - testDenom := res.GetNewTokenDenom() - - _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(testDenom, 10))) - - suite.Require().NoError(err) - - _, err = suite.msgServer.ChangeAdmin(sdk.WrapSDKContext(suite.Ctx), tc.msgChangeAdmin(testDenom)) - - if tc.expectedChangeAdminPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - - queryRes, err := suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ - Denom: testDenom, - }) - suite.Require().NoError(err) - - // expectedAdminIndex with negative value is assumed as admin with value of "" - const emptyStringAdminIndexFlag = -1 - if tc.expectedAdminIndex == emptyStringAdminIndexFlag { - suite.Require().Equal("", queryRes.AuthorityMetadata.Admin) - } else { - suite.Require().Equal(suite.TestAccs[tc.expectedAdminIndex].String(), queryRes.AuthorityMetadata.Admin) - } - - // we test mint to test if admin authority is performed properly after admin change. - if tc.msgMint != nil { - _, err := suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), tc.msgMint(testDenom)) - - if tc.expectedMintPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - } - }) - } -} - -func (suite *KeeperTestSuite) TestSetDenomMetaData() { - - // setup test - suite.SetupTest() - suite.CreateDefaultDenom() - - for _, tc := range []struct { - desc string - msgSetDenomMetadata types.MsgSetDenomMetadata - expectedPass bool - }{ - { - desc: "successful set denom metadata", - msgSetDenomMetadata: *types.NewMsgSetDenomMetadata(suite.TestAccs[0].String(), banktypes.Metadata{ - Description: "test1", - DenomUnits: []*banktypes.DenomUnit{ - { - Denom: suite.defaultDenom, - Exponent: 0, - }, - { - Denom: "usei", - Exponent: 6, - }, - }, - Base: suite.defaultDenom, - Display: "usei", - Name: "SEI", - Symbol: "SEI", - }), - expectedPass: true, - }, - { - desc: "non existent factory denom name", - msgSetDenomMetadata: *types.NewMsgSetDenomMetadata(suite.TestAccs[0].String(), banktypes.Metadata{ - Description: "test2", - DenomUnits: []*banktypes.DenomUnit{ - { - Denom: fmt.Sprintf("factory/%s/litecoin", suite.TestAccs[0].String()), - Exponent: 0, - }, - { - Denom: "usei", - Exponent: 6, - }, - }, - Base: fmt.Sprintf("factory/%s/litecoin", suite.TestAccs[0].String()), - Display: "usei", - Name: "SEI", - Symbol: "SEI", - }), - expectedPass: false, - }, - { - desc: "non-factory denom", - msgSetDenomMetadata: *types.NewMsgSetDenomMetadata(suite.TestAccs[0].String(), banktypes.Metadata{ - Description: "test3", - DenomUnits: []*banktypes.DenomUnit{ - { - Denom: "usei", - Exponent: 0, - }, - { - Denom: "usei", - Exponent: 6, - }, - }, - Base: "usei", - Display: "usei", - Name: "SEI", - Symbol: "SEI", - }), - expectedPass: false, - }, - { - desc: "wrong admin", - msgSetDenomMetadata: *types.NewMsgSetDenomMetadata(suite.TestAccs[1].String(), banktypes.Metadata{ - Description: "test4", - DenomUnits: []*banktypes.DenomUnit{ - { - Denom: suite.defaultDenom, - Exponent: 0, - }, - { - Denom: "usei", - Exponent: 6, - }, - }, - Base: suite.defaultDenom, - Display: "usei", - Name: "SEI", - Symbol: "SEI", - }), - expectedPass: false, - }, - { - desc: "invalid metadata (missing display denom unit)", - msgSetDenomMetadata: *types.NewMsgSetDenomMetadata(suite.TestAccs[0].String(), banktypes.Metadata{ - Description: "test5", - DenomUnits: []*banktypes.DenomUnit{ - { - Denom: suite.defaultDenom, - Exponent: 0, - }, - }, - Base: suite.defaultDenom, - Display: "usei", - Name: "SEI", - Symbol: "SEI", - }), - expectedPass: false, - }, - } { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { - res, err := suite.msgServer.SetDenomMetadata(sdk.WrapSDKContext(suite.Ctx), &tc.msgSetDenomMetadata) - if tc.expectedPass { - suite.Require().NoError(err) - suite.Require().NotNil(res) - - md, found := suite.App.BankKeeper.GetDenomMetaData(suite.Ctx, suite.defaultDenom) - suite.Require().True(found) - suite.Require().Equal(tc.msgSetDenomMetadata.Metadata.Name, md.Name) - } else { - suite.Require().Error(err) - } - }) - } -} diff --git a/x/tokenfactory/keeper/bankactions.go b/x/tokenfactory/keeper/bankactions.go deleted file mode 100644 index 18590f63e3..0000000000 --- a/x/tokenfactory/keeper/bankactions.go +++ /dev/null @@ -1,58 +0,0 @@ -package keeper - -import ( - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" - "github.com/sei-protocol/seilog" -) - -var logger = seilog.NewLogger("x", "tokenfactory", "keeper") - -func (k Keeper) mintTo(ctx sdk.Context, amount sdk.Coin, mintTo string) error { - // verify that denom is an x/tokenfactory denom - _, _, err := types.DeconstructDenom(amount.Denom) - if err != nil { - return err - } - - logger.Info("Minting amount for module", "amount", amount, "module", types.ModuleName) - err = k.bankKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(amount)) - if err != nil { - return err - } - - addr, err := sdk.AccAddressFromBech32(mintTo) - if err != nil { - return err - } - - logger.Info("Sending minted amount to addr", "amount", amount, "addr", addr) - return k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, - addr, - sdk.NewCoins(amount)) -} - -func (k Keeper) burnFrom(ctx sdk.Context, amount sdk.Coin, burnFrom string) error { - // verify that denom is an x/tokenfactory denom - _, _, err := types.DeconstructDenom(amount.Denom) - if err != nil { - return err - } - - addr, err := sdk.AccAddressFromBech32(burnFrom) - if err != nil { - return err - } - - logger.Info("Sending amount to module from account", "amount", amount, "module", types.ModuleName, "account", addr) - err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, - addr, - types.ModuleName, - sdk.NewCoins(amount)) - if err != nil { - return err - } - - logger.Info("Burning amount from module", "amount", amount, "module", types.ModuleName) - return k.bankKeeper.BurnCoins(ctx, types.ModuleName, sdk.NewCoins(amount)) -} diff --git a/x/tokenfactory/keeper/bankactions_test.go b/x/tokenfactory/keeper/bankactions_test.go deleted file mode 100644 index 224eba3684..0000000000 --- a/x/tokenfactory/keeper/bankactions_test.go +++ /dev/null @@ -1,209 +0,0 @@ -package keeper_test - -import ( - "fmt" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -func (suite *KeeperTestSuite) TestMultipleMintsPriorToDeferredSettlement() { - suite.CreateDefaultDenom() - // Make sure that the admin is set correctly - queryRes, err := suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ - Denom: suite.defaultDenom, - }) - suite.Require().NoError(err) - suite.Require().Equal(suite.TestAccs[0].String(), queryRes.AuthorityMetadata.Admin) - - // Test minting to admins own account - _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 50))) - suite.Require().NoError(err) - - _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 5))) - suite.Require().NoError(err) - - addr0Bal := suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom).Amount.Int64() - suite.Require().Equal(int64(55), addr0Bal, addr0Bal) - - tkModuleBal := suite.App.BankKeeper.GetBalance(suite.Ctx, suite.App.AccountKeeper.GetModuleAddress(types.ModuleName), suite.defaultDenom).Amount.Int64() - suite.Require().Equal(int64(0), tkModuleBal, tkModuleBal) -} - -func (suite *KeeperTestSuite) TestMultipleInterleavedMintsBurns() { - suite.CreateDefaultDenom() - // Make sure that the admin is set correctly - queryRes, err := suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ - Denom: suite.defaultDenom, - }) - suite.Require().NoError(err) - suite.Require().Equal(suite.TestAccs[0].String(), queryRes.AuthorityMetadata.Admin) - - // Test minting to admins own account - _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 50))) - suite.Require().NoError(err) - - addr0Bal := suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom).Amount.Int64() - suite.Require().Equal(int64(50), addr0Bal, addr0Bal) - - tkModuleBal := suite.App.BankKeeper.GetBalance(suite.Ctx, suite.App.AccountKeeper.GetModuleAddress(types.ModuleName), suite.defaultDenom).Amount.Int64() - suite.Require().Equal(int64(0), tkModuleBal, tkModuleBal) - - // Test two burns back to back - _, err = suite.msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 10))) - suite.Require().NoError(err) - - _, err = suite.msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 15))) - suite.Require().NoError(err) - - // Try burning more than what's left - _, err = suite.msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 100))) - suite.Require().Error(err) - - // Check balances after burns - addr0Bal = suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom).Amount.Int64() - suite.Require().Equal(int64(25), addr0Bal, addr0Bal) - - tkModuleBal = suite.App.BankKeeper.GetBalance(suite.Ctx, suite.App.AccountKeeper.GetModuleAddress(types.ModuleName), suite.defaultDenom).Amount.Int64() - suite.Require().Equal(int64(0), tkModuleBal, tkModuleBal) - - // Mint Incorrect Denom - _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin("incorrectDenom", 60))) - suite.Require().Error(err) - - // Mint from non-admin account - _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[1].String(), sdk.NewInt64Coin(suite.defaultDenom, 60))) - suite.Require().Error(err) - - // Final valid mint and burn - _, err = suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 10))) - suite.Require().NoError(err) - - _, err = suite.msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 5))) - suite.Require().NoError(err) - - // Check final balances - addr0Bal = suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom).Amount.Int64() - suite.Require().Equal(int64(30), addr0Bal, addr0Bal) - - tkModuleBal = suite.App.BankKeeper.GetBalance(suite.Ctx, suite.App.AccountKeeper.GetModuleAddress(types.ModuleName), suite.defaultDenom).Amount.Int64() - suite.Require().Equal(int64(0), tkModuleBal, tkModuleBal) -} - -// TestMintDenom ensures the following properties of the MintMessage: -// * No one can mint tokens for a denom that doesn't exist -// * Only the admin of a denom can mint tokens for it -// * The admin of a denom can mint tokens for it -func (suite *KeeperTestSuite) TestMintDenom() { - var addr0bal int64 - - // Create a denom - suite.CreateDefaultDenom() - - for _, tc := range []struct { - desc string - amount int64 - mintDenom string - admin string - valid bool - }{ - { - desc: "denom does not exist", - amount: 10, - mintDenom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/evmos", - admin: suite.TestAccs[0].String(), - valid: false, - }, - { - desc: "mint is not by the admin", - amount: 10, - mintDenom: suite.defaultDenom, - admin: suite.TestAccs[1].String(), - valid: false, - }, - { - desc: "success case", - amount: 10, - mintDenom: suite.defaultDenom, - admin: suite.TestAccs[0].String(), - valid: true, - }, - } { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { - // Test minting to admins own account - _, err := suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(tc.admin, sdk.NewInt64Coin(tc.mintDenom, 10))) - - if tc.valid { - addr0bal += 10 - suite.Require().NoError(err) - suite.Require().Equal(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom).Amount.Int64(), addr0bal, suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom)) - } else { - suite.Require().Error(err) - } - }) - } -} - -func (suite *KeeperTestSuite) TestBurnDenom() { - var addr0bal int64 - - // Create a denom. - suite.CreateDefaultDenom() - - // mint 10 default token for testAcc[0] - suite.msgServer.Mint(sdk.WrapSDKContext(suite.Ctx), types.NewMsgMint(suite.TestAccs[0].String(), sdk.NewInt64Coin(suite.defaultDenom, 10))) - - addr0bal += 10 - - for _, tc := range []struct { - desc string - amount int64 - burnDenom string - admin string - valid bool - }{ - { - desc: "denom does not exist", - amount: 10, - burnDenom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/evmos", - admin: suite.TestAccs[0].String(), - valid: false, - }, - { - desc: "burn is not by the admin", - amount: 10, - burnDenom: suite.defaultDenom, - admin: suite.TestAccs[1].String(), - valid: false, - }, - { - desc: "burn amount is bigger than minted amount", - amount: 1000, - burnDenom: suite.defaultDenom, - admin: suite.TestAccs[1].String(), - valid: false, - }, - { - desc: "success case", - amount: 10, - burnDenom: suite.defaultDenom, - admin: suite.TestAccs[0].String(), - valid: true, - }, - } { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { - // Test minting to admins own account - _, err := suite.msgServer.Burn(sdk.WrapSDKContext(suite.Ctx), types.NewMsgBurn(tc.admin, sdk.NewInt64Coin(tc.burnDenom, 10))) - - if tc.valid { - addr0bal -= 10 - suite.Require().NoError(err) - suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom).Amount.Int64() == addr0bal, suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom)) - } else { - suite.Require().Error(err) - suite.Require().True(suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom).Amount.Int64() == addr0bal, suite.App.BankKeeper.GetBalance(suite.Ctx, suite.TestAccs[0], suite.defaultDenom)) - } - }) - } -} diff --git a/x/tokenfactory/keeper/createdenom.go b/x/tokenfactory/keeper/createdenom.go deleted file mode 100644 index 11d67b4c04..0000000000 --- a/x/tokenfactory/keeper/createdenom.go +++ /dev/null @@ -1,113 +0,0 @@ -package keeper - -import ( - "fmt" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -// CreateDenom creates a new token denom with the given subdenom. -func (k Keeper) CreateDenom(ctx sdk.Context, creatorAddr string, subdenom string) (newTokenDenom string, err error) { - denom, err := k.validateCreateDenom(ctx, creatorAddr, subdenom) - if err != nil { - return "", err - } - - err = k.createDenomAfterValidation(ctx, creatorAddr, denom) - return denom, err -} - -// Runs CreateDenom logic after the charge and all denom validation has been handled. -// Made into a second function for genesis initialization. -func (k Keeper) createDenomAfterValidation(ctx sdk.Context, creatorAddr string, denom string) (err error) { - denomMetaData := banktypes.Metadata{ - DenomUnits: []*banktypes.DenomUnit{{ - Denom: denom, - Exponent: 0, - }}, - Base: denom, - // The following is necessary for x/bank denom validation - Display: denom, - Name: denom, - Symbol: denom, - } - - k.bankKeeper.SetDenomMetaData(ctx, denomMetaData) - - authorityMetadata := types.DenomAuthorityMetadata{ - Admin: creatorAddr, - } - err = k.setAuthorityMetadata(ctx, denom, authorityMetadata) - if err != nil { - return err - } - - k.addDenomFromCreator(ctx, creatorAddr, denom) - return nil -} - -func (k Keeper) validateCreateDenom(ctx sdk.Context, creatorAddr string, subdenom string) (newTokenDenom string, err error) { - // A subdenom must not collide with a denom that already has supply. - if k.bankKeeper.HasSupply(ctx, subdenom) { - return "", fmt.Errorf("can't create subdenoms that are the same as a native denom") - } - - denom, err := types.GetTokenDenom(creatorAddr, subdenom) - if err != nil { - return "", err - } - - _, found := k.bankKeeper.GetDenomMetaData(ctx, denom) - if found { - return "", types.ErrDenomExists - } - - return denom, nil -} - -func (k Keeper) validateUpdateDenom(ctx sdk.Context, msg *types.MsgUpdateDenom) (tokenDenom string, err error) { - _, _, err = types.DeconstructDenom(msg.GetDenom()) - if err != nil { - return "", err - } - _, found := k.bankKeeper.GetDenomMetaData(ctx, msg.GetDenom()) - if !found { - return "", types.ErrDenomDoesNotExist.Wrapf("denom: %s", msg.GetDenom()) - } - - err = k.validateAllowList(ctx, msg.AllowList) - if err != nil { - return "", err - } - - return msg.GetDenom(), nil -} - -func (k Keeper) validateAllowListSize(ctx sdk.Context, allowList *banktypes.AllowList) error { - if allowList == nil { - return types.ErrAllowListUndefined - } - - if len(allowList.Addresses) > int(k.GetDenomAllowListMaxSize(ctx)) { - return types.ErrAllowListTooLarge - } - return nil -} - -func (k Keeper) validateAllowList(ctx sdk.Context, allowList *banktypes.AllowList) error { - err := k.validateAllowListSize(ctx, allowList) - if err != nil { - return err - } - - // validate all addresses in the allow list are bech32 - for _, addr := range allowList.Addresses { - if _, err = sdk.AccAddressFromBech32(addr); err != nil { - return fmt.Errorf("invalid address %s: %w", addr, err) - } - } - return nil -} diff --git a/x/tokenfactory/keeper/createdenom_test.go b/x/tokenfactory/keeper/createdenom_test.go deleted file mode 100644 index 707fa4a569..0000000000 --- a/x/tokenfactory/keeper/createdenom_test.go +++ /dev/null @@ -1,290 +0,0 @@ -package keeper_test - -import ( - "fmt" - - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -func (suite *KeeperTestSuite) TestMsgCreateDenom() { - - // Creating a denom should work - res, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "bitcoin")) - suite.Require().NoError(err) - suite.Require().NotEmpty(res.GetNewTokenDenom()) - - // Make sure that the admin is set correctly - queryRes, err := suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ - Denom: res.GetNewTokenDenom(), - }) - suite.Require().NoError(err) - suite.Require().Equal(suite.TestAccs[0].String(), queryRes.AuthorityMetadata.Admin) - - // Make sure that a second version of the same denom can't be recreated - res, err = suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "bitcoin")) - suite.Require().Error(err) - - // Creating a second denom should work - res, err = suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "litecoin")) - suite.Require().NoError(err) - suite.Require().NotEmpty(res.GetNewTokenDenom()) - - // Try querying all the denoms created by suite.TestAccs[0] - queryRes2, err := suite.queryClient.DenomsFromCreator(suite.Ctx.Context(), &types.QueryDenomsFromCreatorRequest{ - Creator: suite.TestAccs[0].String(), - }) - suite.Require().NoError(err) - suite.Require().Len(queryRes2.Denoms, 2) - - // Make sure that a second account can create a denom with the same subdenom - res, err = suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[1].String(), "bitcoin")) - suite.Require().NoError(err) - suite.Require().NotEmpty(res.GetNewTokenDenom()) - - // Make sure that an address with a "/" in it can't create denoms - res, err = suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom("sei.eth/creator", "bitcoin")) - suite.Require().Error(err) -} - -func (suite *KeeperTestSuite) TestCreateDenom() { - params, _ := suite.queryClient.Params(suite.Ctx.Context(), &types.QueryParamsRequest{}) - allowListSize := params.Params.DenomAllowlistMaxSize - largeAllowList := make([]string, allowListSize+1) - for _, tc := range []struct { - desc string - setup func() - subdenom string - allowList *banktypes.AllowList - valid bool - }{ - { - desc: "subdenom too long", - subdenom: "assadsadsadasdasdsadsadsadsadsadsadsklkadaskkkdasdasedskhanhassyeunganassfnlksdflksafjlkasd", - valid: false, - }, - { - desc: "subdenom and creator pair already exists", - setup: func() { - _, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "bitcoin")) - suite.Require().NoError(err) - }, - subdenom: "bitcoin", - valid: false, - }, - { - desc: "success case", - subdenom: "evmos", - valid: true, - }, - { - desc: "subdenom having invalid characters", - subdenom: "bit/***///&&&/coin", - valid: false, - }, - { - desc: "valid allow list", - subdenom: "withallowlist", - allowList: &banktypes.AllowList{ - Addresses: []string{suite.TestAccs[0].String(), suite.TestAccs[1].String(), suite.TestAccs[2].String()}, - }, - valid: true, - }, - { - desc: "invalid allow list with invalid address", - subdenom: "invalidallowlist", - allowList: &banktypes.AllowList{ - Addresses: []string{"invalid_address"}, - }, - valid: false, - }, - { - desc: "list is too large", - subdenom: "test", - allowList: &banktypes.AllowList{Addresses: largeAllowList}, - valid: false, - }, - } { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { - if tc.setup != nil { - tc.setup() - } - - msg := types.NewMsgCreateDenom(suite.TestAccs[0].String(), tc.subdenom) - if tc.allowList != nil { - msg.AllowList = tc.allowList - } - - // Create a denom - res, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), msg) - if tc.valid { - suite.Require().NoError(err) - - // Make sure that the admin is set correctly - queryRes, err := suite.queryClient.DenomAuthorityMetadata(suite.Ctx.Context(), &types.QueryDenomAuthorityMetadataRequest{ - Denom: res.GetNewTokenDenom(), - }) - - suite.Require().NoError(err) - suite.Require().Equal(suite.TestAccs[0].String(), queryRes.AuthorityMetadata.Admin) - - // Make sure that the denom is valid from the perspective of x/bank - bankQueryRes, err := suite.bankQueryClient.DenomMetadata(suite.Ctx.Context(), &banktypes.QueryDenomMetadataRequest{ - Denom: res.GetNewTokenDenom(), - }) - - suite.Require().NoError(err) - suite.Require().NoError(bankQueryRes.Metadata.Validate()) - - // Verify the allow list if provided - if tc.allowList != nil { - allowListRes, err := suite.queryClient.DenomAllowList(suite.Ctx.Context(), &types.QueryDenomAllowListRequest{ - Denom: res.GetNewTokenDenom(), - }) - suite.Require().NoError(err) - suite.Require().Equal(tc.allowList, &allowListRes.AllowList) - } - } else { - suite.Require().Error(err) - } - }) - } -} - -func (suite *KeeperTestSuite) TestUpdateDenom() { - params, _ := suite.queryClient.Params(suite.Ctx.Context(), &types.QueryParamsRequest{}) - allowListSize := params.Params.DenomAllowlistMaxSize - largeAllowList := make([]string, allowListSize+1) - for _, tc := range []struct { - desc string - setup func() - sender string - denom string - allowList *banktypes.AllowList // Ensure this is the correct type for your allow list - valid bool - errMsg string - }{ - { - desc: "denom too long", - denom: fmt.Sprintf("factory/%s/assadsadsadasdasdsadsadsadsadsadsadsklkadaskkkdasdasedskhanhassyeunganassfnlksdflksafjlkasd", suite.TestAccs[0].String()), - valid: false, - errMsg: fmt.Sprintf("invalid denom: factory/%s/assadsadsadasdasdsadsadsadsadsadsadsklkadaskkkdasdasedskhanhassyeunganassfnlksdflksafjlkasd", suite.TestAccs[0].String()), - }, - { - desc: "denom missing parts", - denom: "nonexistent", - valid: false, - errMsg: "not enough parts of denom nonexistent: invalid denom", - }, - { - desc: "denom allow list can be updated", - setup: func() { - _, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), - types.NewMsgCreateDenom(suite.TestAccs[0].String(), "UPD")) - suite.Require().NoError(err) - }, - denom: fmt.Sprintf("factory/%s/UPD", suite.TestAccs[0].String()), - allowList: &banktypes.AllowList{ - Addresses: []string{suite.TestAccs[0].String(), suite.TestAccs[1].String()}, - }, - valid: true, - }, - { - desc: "denom allow list can be updated with empty list", - setup: func() { - _, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), - types.NewMsgCreateDenom(suite.TestAccs[0].String(), "EMPT")) - suite.Require().NoError(err) - }, - denom: fmt.Sprintf("factory/%s/EMPT", suite.TestAccs[0].String()), - allowList: &banktypes.AllowList{}, - valid: true, - }, - { - desc: "error if allow list is undefined", - setup: func() { - _, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), - types.NewMsgCreateDenom(suite.TestAccs[0].String(), "UND")) - suite.Require().NoError(err) - }, - denom: fmt.Sprintf("factory/%s/UND", suite.TestAccs[0].String()), - allowList: nil, - valid: false, - errMsg: "allowlist undefined", - }, - { - desc: "error if allow list is too large", - setup: func() { - _, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), - types.NewMsgCreateDenom(suite.TestAccs[0].String(), "TLRG")) - suite.Require().NoError(err) - }, - denom: fmt.Sprintf("factory/%s/TLRG", suite.TestAccs[0].String()), - allowList: &banktypes.AllowList{Addresses: largeAllowList}, - valid: false, - errMsg: "allowlist too large", - }, - { - desc: "denom having invalid characters", - denom: "bit/***///&&&/coin", - valid: false, - errMsg: "invalid denom: bit/***///&&&/coin", - }, - { - desc: "invalid allow list with invalid address", - setup: func() { - _, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "invalidallowlist")) - suite.Require().NoError(err) - }, - denom: fmt.Sprintf("factory/%s/invalidallowlist", suite.TestAccs[0].String()), - allowList: &banktypes.AllowList{ - Addresses: []string{"invalid_address"}, - }, - valid: false, - errMsg: "invalid address invalid_address: decoding bech32 failed: invalid separator index -1", - }, - { - desc: "sender is not the admin", - setup: func() { - _, err := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "SND")) - suite.Require().NoError(err) - }, - denom: fmt.Sprintf("factory/%s/SND", suite.TestAccs[0].String()), - sender: suite.TestAccs[1].String(), - allowList: &banktypes.AllowList{}, - valid: false, - errMsg: "unauthorized account", - }, - } { - suite.Run(fmt.Sprintf("Case %s", tc.desc), func() { - if tc.setup != nil { - tc.setup() - } - if tc.sender == "" { - tc.sender = suite.TestAccs[0].String() - } - msg := types.NewMsgUpdateDenom(tc.sender, tc.denom, tc.allowList) - - // Update a denom - _, err := suite.msgServer.UpdateDenom(sdk.WrapSDKContext(suite.Ctx), msg) - if tc.valid { - suite.Require().NoError(err) - - // Verify the allow list if provided - if tc.allowList != nil { - allowListRes, err := suite.queryClient.DenomAllowList(suite.Ctx.Context(), &types.QueryDenomAllowListRequest{ - Denom: tc.denom, - }) - suite.Require().NoError(err) - suite.Require().Equal(tc.allowList, &allowListRes.AllowList) - } - } else { - suite.Require().Error(err) - suite.Require().Equal(tc.errMsg, err.Error()) - } - }) - } -} diff --git a/x/tokenfactory/keeper/creators.go b/x/tokenfactory/keeper/creators.go deleted file mode 100644 index 0686dd44e4..0000000000 --- a/x/tokenfactory/keeper/creators.go +++ /dev/null @@ -1,41 +0,0 @@ -package keeper - -import ( - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - "github.com/sei-protocol/sei-chain/sei-cosmos/types/query" -) - -func (k Keeper) addDenomFromCreator(ctx sdk.Context, creator, denom string) { - store := k.GetCreatorPrefixStore(ctx, creator) - store.Set([]byte(denom), []byte(denom)) -} - -func (k Keeper) getDenomsFromCreator(ctx sdk.Context, creator string, pagination *query.PageRequest) ([]string, *query.PageResponse, error) { - store := k.GetCreatorPrefixStore(ctx, creator) - var denoms []string - pageRes, err := query.Paginate(ctx, store, pagination, func(key []byte, _ []byte) error { - denoms = append(denoms, string(key)) - return nil - }) - if err != nil { - return nil, nil, err - } - return denoms, pageRes, nil -} - -// GetAllDenomsFromCreator returns every denom for a creator with no page cap. -// Safe to use in the wasm query path: gas metering bounds execution cost, so unbounded iteration does not pose a DoS risk. -func (k Keeper) GetAllDenomsFromCreator(ctx sdk.Context, creator string) []string { - store := k.GetCreatorPrefixStore(ctx, creator) - iterator := store.Iterator(nil, nil) - defer func() { _ = iterator.Close() }() - var denoms []string - for ; iterator.Valid(); iterator.Next() { - denoms = append(denoms, string(iterator.Key())) - } - return denoms -} - -func (k Keeper) GetAllDenomsIterator(ctx sdk.Context) sdk.Iterator { - return k.GetCreatorsPrefixStore(ctx).Iterator(nil, nil) -} diff --git a/x/tokenfactory/keeper/genesis.go b/x/tokenfactory/keeper/genesis.go deleted file mode 100644 index a5c3234e33..0000000000 --- a/x/tokenfactory/keeper/genesis.go +++ /dev/null @@ -1,30 +0,0 @@ -package keeper - -import ( - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -// InitGenesis initializes the tokenfactory module's state from a provided genesis -// state. -func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) { - k.CreateModuleAccount(ctx) - - k.SetParams(ctx, genState.Params) - - for _, genDenom := range genState.GetFactoryDenoms() { - creator, _, err := types.DeconstructDenom(genDenom.GetDenom()) - if err != nil { - panic(err) - } - err = k.createDenomAfterValidation(ctx, creator, genDenom.GetDenom()) - if err != nil { - panic(err) - } - err = k.setAuthorityMetadata(ctx, genDenom.GetDenom(), genDenom.GetAuthorityMetadata()) - if err != nil { - panic(err) - } - } -} diff --git a/x/tokenfactory/keeper/genesis_test.go b/x/tokenfactory/keeper/genesis_test.go deleted file mode 100644 index ccec9b947b..0000000000 --- a/x/tokenfactory/keeper/genesis_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package keeper_test - -import ( - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - tmproto "github.com/sei-protocol/sei-chain/sei-tendermint/proto/tendermint/types" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -func (suite *KeeperTestSuite) TestGenesis() { - genesisState := types.GenesisState{ - FactoryDenoms: []types.GenesisDenom{ - { - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/bitcoin", - AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - }, - }, - { - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/diff-admin", - AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "sei1hjfwcza3e3uzeznf3qthhakdr9juetl7g6esl4", - }, - }, - { - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/litecoin", - AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - }, - }, - }, - } - app := suite.App - suite.Ctx = app.BaseApp.NewContext(false, tmproto.Header{}) - // Test both with bank denom metadata set, and not set. - for i, denom := range genesisState.FactoryDenoms { - // hacky, sets bank metadata to exist if i != 0, to cover both cases. - if i != 0 { - app.BankKeeper.SetDenomMetaData(suite.Ctx, banktypes.Metadata{Base: denom.GetDenom()}) - } - } - - app.TokenFactoryKeeper.InitGenesis(suite.Ctx, genesisState) - var denoms []string - iterator := app.TokenFactoryKeeper.GetAllDenomsIterator(suite.Ctx) - for ; iterator.Valid(); iterator.Next() { - denoms = append(denoms, string(iterator.Value())) - } - suite.Require().NoError(iterator.Close()) - suite.Require().Len(denoms, len(genesisState.FactoryDenoms)) - for i, denom := range genesisState.FactoryDenoms { - suite.Require().Equal(denom.Denom, denoms[i]) - metadata, err := app.TokenFactoryKeeper.GetAuthorityMetadata(suite.Ctx, denom.Denom) - suite.Require().NoError(err) - suite.Require().Equal(denom.AuthorityMetadata, metadata) - } - suite.Require().Equal(genesisState.Params, app.TokenFactoryKeeper.GetParams(suite.Ctx)) -} diff --git a/x/tokenfactory/keeper/grpc_query.go b/x/tokenfactory/keeper/grpc_query.go deleted file mode 100644 index da7daf80e6..0000000000 --- a/x/tokenfactory/keeper/grpc_query.go +++ /dev/null @@ -1,79 +0,0 @@ -package keeper - -import ( - "context" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -var _ types.QueryServer = Keeper{} - -func (k Keeper) Params(ctx context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { - sdkCtx := sdk.UnwrapSDKContext(ctx) - params := k.GetParams(sdkCtx) - - return &types.QueryParamsResponse{Params: params}, nil -} - -func (k Keeper) DenomAuthorityMetadata(ctx context.Context, req *types.QueryDenomAuthorityMetadataRequest) (*types.QueryDenomAuthorityMetadataResponse, error) { - sdkCtx := sdk.UnwrapSDKContext(ctx) - - authorityMetadata, err := k.GetAuthorityMetadata(sdkCtx, req.GetDenom()) - if err != nil { - return nil, err - } - - return &types.QueryDenomAuthorityMetadataResponse{AuthorityMetadata: authorityMetadata}, nil -} - -func (k Keeper) DenomsFromCreator(ctx context.Context, req *types.QueryDenomsFromCreatorRequest) (*types.QueryDenomsFromCreatorResponse, error) { - sdkCtx := sdk.UnwrapSDKContext(ctx) - denoms, pageRes, err := k.getDenomsFromCreator(sdkCtx, req.GetCreator(), req.GetPagination()) - if err != nil { - return nil, err - } - return &types.QueryDenomsFromCreatorResponse{Denoms: denoms, Pagination: pageRes}, nil -} - -// DenomMetadata implements Query/DenomMetadata gRPC method. -func (k Keeper) DenomMetadata(c context.Context, req *types.QueryDenomMetadataRequest) (*types.QueryDenomMetadataResponse, error) { - if req == nil { - return nil, status.Errorf(codes.InvalidArgument, "empty request") - } - - if req.Denom == "" { - return nil, status.Error(codes.InvalidArgument, "invalid denom") - } - - ctx := sdk.UnwrapSDKContext(c) - - metadata, found := k.bankKeeper.GetDenomMetaData(ctx, req.Denom) - if !found { - return nil, status.Errorf(codes.NotFound, "client metadata for denom %s", req.Denom) - } - - return &types.QueryDenomMetadataResponse{ - Metadata: metadata, - }, nil -} - -func (k Keeper) DenomAllowList(c context.Context, req *types.QueryDenomAllowListRequest) (*types.QueryDenomAllowListResponse, error) { - if req == nil { - return nil, status.Errorf(codes.InvalidArgument, "empty request") - } - - if req.Denom == "" { - return nil, status.Error(codes.InvalidArgument, "invalid denom") - } - - ctx := sdk.UnwrapSDKContext(c) - - allowList := k.bankKeeper.GetDenomAllowList(ctx, req.Denom) - return &types.QueryDenomAllowListResponse{ - AllowList: allowList, - }, nil -} diff --git a/x/tokenfactory/keeper/grpc_query_test.go b/x/tokenfactory/keeper/grpc_query_test.go deleted file mode 100644 index 01cae67859..0000000000 --- a/x/tokenfactory/keeper/grpc_query_test.go +++ /dev/null @@ -1,273 +0,0 @@ -package keeper_test - -import ( - "context" - "fmt" - "reflect" - "testing" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - "github.com/sei-protocol/sei-chain/sei-cosmos/types/query" - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - "github.com/sei-protocol/sei-chain/x/tokenfactory/keeper" - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -func (suite *KeeperTestSuite) TestDenomMetadataRequest() { - var ( - req *types.QueryDenomMetadataRequest - expMetadata = banktypes.Metadata{} - ) - tokenFactoryDenom := "factory/sei1gxskuzvhr4s8sdm2rpruaf7yx2dnmjn0zfdu9q/NEWCOIN" - testCases := []struct { - msg string - malleate func() - expPass bool - }{ - { - "empty denom", - func() { - req = &types.QueryDenomMetadataRequest{} - }, - false, - }, - { - "not found denom", - func() { - req = &types.QueryDenomMetadataRequest{ - Denom: tokenFactoryDenom, - } - }, - false, - }, - { - "success", - func() { - - expMetadata = banktypes.Metadata{ - Description: "Token factory custom token", - DenomUnits: []*banktypes.DenomUnit{ - { - Denom: tokenFactoryDenom, - Exponent: 0, - Aliases: []string{tokenFactoryDenom}, - }, - }, - Base: tokenFactoryDenom, - Display: tokenFactoryDenom, - } - - suite.App.BankKeeper.SetDenomMetaData(suite.Ctx, expMetadata) - req = &types.QueryDenomMetadataRequest{ - Denom: expMetadata.Base, - } - }, - true, - }, - } - - for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { - suite.SetupTest() // reset - - tc.malleate() - ctx := sdk.WrapSDKContext(suite.Ctx) - - res, err := suite.queryClient.DenomMetadata(ctx, req) - - if tc.expPass { - suite.Require().NoError(err) - suite.Require().NotNil(res) - suite.Require().Equal(expMetadata, res.Metadata) - } else { - suite.Require().Error(err) - } - }) - } -} - -func (suite *KeeperTestSuite) TestDenomAllowListRequest() { - - tokenFactoryDenom := "factory/sei1gxskuzvhr4s8sdm2rpruaf7yx2dnmjn0zfdu9q/NEWCOIN" - allowList := banktypes.AllowList{ - Addresses: []string{"sei1gxskuzvhr4s8sdm2rpruaf7yx2dnmjn0zfdu9q", "sei1gxskuzvhr4s8sdm2rpruaf7yx2dnmjn0zfdu8q"}, - } - type args struct { - req *types.QueryDenomAllowListRequest - } - testCases := []struct { - name string - args args - malleate func() - expAllowList banktypes.AllowList - expectedError string - wantErr bool - }{ - { - name: "fails on empty denom", - malleate: func() {}, - args: args{ - req: &types.QueryDenomAllowListRequest{}, - }, - expectedError: "rpc error: code = InvalidArgument desc = invalid denom", - wantErr: true, - }, - { - name: "returns empty list for denom that does not have allow list", - malleate: func() {}, - args: args{ - req: &types.QueryDenomAllowListRequest{ - Denom: tokenFactoryDenom, - }, - }, - expAllowList: banktypes.AllowList{}, - wantErr: false, - }, - { - name: "returns allow list for denom that has allow list", - malleate: func() { - suite.App.BankKeeper.SetDenomAllowList(suite.Ctx, tokenFactoryDenom, allowList) - }, - args: args{ - req: &types.QueryDenomAllowListRequest{ - Denom: tokenFactoryDenom, - }, - }, - expAllowList: allowList, - wantErr: false, - }, - } - - for _, tc := range testCases { - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - tc.malleate() - ctx := sdk.WrapSDKContext(suite.Ctx) - - res, err := suite.queryClient.DenomAllowList(ctx, tc.args.req) - - if tc.wantErr { - suite.Require().Error(err) - suite.Require().Contains(err.Error(), tc.expectedError) - } else { - suite.Require().NoError(err) - suite.Require().NotNil(res) - suite.Require().Equal(tc.expAllowList, res.AllowList) - } - }) - } -} - -func (suite *KeeperTestSuite) TestDenomsFromCreatorPagination() { - creator := suite.TestAccs[0].String() - ctx := sdk.WrapSDKContext(suite.Ctx) - - denomSubdirs := []string{"aaa", "bbb", "ccc", "ddd", "eee"} - for _, sub := range denomSubdirs { - _, err := suite.msgServer.CreateDenom(ctx, types.NewMsgCreateDenom(creator, sub)) - suite.Require().NoError(err) - } - - suite.Run("no pagination returns all denoms", func() { - res, err := suite.queryClient.DenomsFromCreator(ctx, &types.QueryDenomsFromCreatorRequest{Creator: creator}) - suite.Require().NoError(err) - suite.Require().Len(res.Denoms, len(denomSubdirs)) - suite.Require().NotNil(res.Pagination) - }) - - suite.Run("limit 2 returns first page with next key", func() { - res, err := suite.queryClient.DenomsFromCreator(ctx, &types.QueryDenomsFromCreatorRequest{ - Creator: creator, - Pagination: &query.PageRequest{Limit: 2}, - }) - suite.Require().NoError(err) - suite.Require().Len(res.Denoms, 2) - suite.Require().NotNil(res.Pagination) - suite.Require().NotNil(res.Pagination.NextKey) - }) - - suite.Run("key-based second page returns remaining denoms", func() { - first, err := suite.queryClient.DenomsFromCreator(ctx, &types.QueryDenomsFromCreatorRequest{ - Creator: creator, - Pagination: &query.PageRequest{Limit: 2}, - }) - suite.Require().NoError(err) - - second, err := suite.queryClient.DenomsFromCreator(ctx, &types.QueryDenomsFromCreatorRequest{ - Creator: creator, - Pagination: &query.PageRequest{Key: first.Pagination.NextKey, Limit: 2}, - }) - suite.Require().NoError(err) - suite.Require().NotEmpty(second.Denoms) - // pages must not overlap - for _, d := range second.Denoms { - suite.Require().NotContains(first.Denoms, d) - } - }) - - suite.Run("offset-based pagination", func() { - all, err := suite.queryClient.DenomsFromCreator(ctx, &types.QueryDenomsFromCreatorRequest{Creator: creator}) - suite.Require().NoError(err) - - const offset = 2 - res, err := suite.queryClient.DenomsFromCreator(ctx, &types.QueryDenomsFromCreatorRequest{ - Creator: creator, - Pagination: &query.PageRequest{Offset: offset, Limit: 2}, - }) - suite.Require().NoError(err) - suite.Require().NotEmpty(res.Denoms) - suite.Require().Equal(all.Denoms[offset:offset+len(res.Denoms)], res.Denoms) - }) -} - -func TestKeeper_DenomAllowList(t *testing.T) { - type args struct { - req *types.QueryDenomAllowListRequest - c context.Context - } - tests := []struct { - name string - args args - want *types.QueryDenomAllowListResponse - wantErr bool - errMsg string - }{ - { - name: "nil request", - args: args{ - req: nil, - c: context.Background(), - }, - wantErr: true, - errMsg: "rpc error: code = InvalidArgument desc = empty request", - }, - { - name: "empty denom", - args: args{ - req: &types.QueryDenomAllowListRequest{}, - c: context.Background(), - }, - wantErr: true, - errMsg: "rpc error: code = InvalidArgument desc = invalid denom", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - k := keeper.Keeper{} - got, err := k.DenomAllowList(tt.args.c, tt.args.req) - if (err != nil) != tt.wantErr { - t.Errorf("DenomAllowList() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.wantErr && err != nil && err.Error() != tt.errMsg { - t.Errorf("DenomAllowList() error = %v, wantErr %v", err, tt.errMsg) - return - } - if !tt.wantErr && !reflect.DeepEqual(got, tt.want) { - t.Errorf("DenomAllowList() got = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/x/tokenfactory/keeper/keeper.go b/x/tokenfactory/keeper/keeper.go deleted file mode 100644 index bee3d12152..0000000000 --- a/x/tokenfactory/keeper/keeper.go +++ /dev/null @@ -1,80 +0,0 @@ -package keeper - -import ( - "github.com/sei-protocol/sei-chain/sei-cosmos/codec" - "github.com/sei-protocol/sei-chain/sei-cosmos/store/prefix" - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" - - authtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/auth/types" - paramtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/params/types" -) - -type ( - Keeper struct { - storeKey sdk.StoreKey - - paramSpace paramtypes.Subspace - - accountKeeper types.AccountKeeper - bankKeeper types.BankKeeper - distrKeeper types.DistrKeeper - } -) - -// NewKeeper returns a new instance of the x/tokenfactory keeper -func NewKeeper( - _ codec.Codec, - storeKey sdk.StoreKey, - paramSpace paramtypes.Subspace, - accountKeeper types.AccountKeeper, - bankKeeper types.BankKeeper, - distrKeeper types.DistrKeeper, -) Keeper { - if !paramSpace.HasKeyTable() { - paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) - } - - return Keeper{ - storeKey: storeKey, - paramSpace: paramSpace, - - accountKeeper: accountKeeper, - bankKeeper: bankKeeper, - distrKeeper: distrKeeper, - } -} - -// GetDenomPrefixStore returns the substore for a specific denom -func (k Keeper) GetDenomPrefixStore(ctx sdk.Context, denom string) sdk.KVStore { - store := ctx.KVStore(k.storeKey) - return prefix.NewStore(store, types.GetDenomPrefixStore(denom)) -} - -// GetCreatorPrefixStore returns the substore for a specific creator address -func (k Keeper) GetCreatorPrefixStore(ctx sdk.Context, creator string) sdk.KVStore { - store := ctx.KVStore(k.storeKey) - return prefix.NewStore(store, types.GetCreatorPrefix(creator)) -} - -// GetCreatorsPrefixStore returns the substore that contains a list of creators -func (k Keeper) GetCreatorsPrefixStore(ctx sdk.Context) sdk.KVStore { - store := ctx.KVStore(k.storeKey) - return prefix.NewStore(store, types.GetCreatorsPrefix()) -} - -// CreateModuleAccount creates a module account with minting and burning capabilities -// This account isn't intended to store any coins, -// it purely mints and burns them on behalf of the admin of respective denoms, -// and sends to the relevant address. -func (k Keeper) CreateModuleAccount(ctx sdk.Context) { - moduleAcc := authtypes.NewEmptyModuleAccount(types.ModuleName, authtypes.Minter, authtypes.Burner) - k.accountKeeper.SetModuleAccount(ctx, moduleAcc) -} - -func (k Keeper) GetDenomAllowListMaxSize(ctx sdk.Context) uint32 { - var denomAllowListMaxSize uint32 - k.paramSpace.Get(ctx, types.DenomAllowListMaxSizeKey, &denomAllowListMaxSize) - return denomAllowListMaxSize -} diff --git a/x/tokenfactory/keeper/keeper_test.go b/x/tokenfactory/keeper/keeper_test.go deleted file mode 100644 index 9194756312..0000000000 --- a/x/tokenfactory/keeper/keeper_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package keeper_test - -import ( - "testing" - - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - tmproto "github.com/sei-protocol/sei-chain/sei-tendermint/proto/tendermint/types" - "github.com/stretchr/testify/suite" - - "github.com/sei-protocol/sei-chain/app/apptesting" - "github.com/sei-protocol/sei-chain/x/tokenfactory/keeper" - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -type KeeperTestSuite struct { - apptesting.KeeperTestHelper - - queryClient types.QueryClient - bankQueryClient banktypes.QueryClient - msgServer types.MsgServer - // defaultDenom is on the suite, as it depends on the creator test address. - defaultDenom string -} - -func TestKeeperTestSuite(t *testing.T) { - suite.Run(t, new(KeeperTestSuite)) -} - -func (suite *KeeperTestSuite) SetupTest() { - suite.Setup() - - suite.SetupTokenFactory() - - suite.queryClient = types.NewQueryClient(suite.QueryHelper) - suite.bankQueryClient = banktypes.NewQueryClient(suite.QueryHelper) - suite.msgServer = keeper.NewMsgServerImpl(suite.App.TokenFactoryKeeper) -} - -func (suite *KeeperTestSuite) CreateDefaultDenom() { - res, _ := suite.msgServer.CreateDenom(sdk.WrapSDKContext(suite.Ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), "bitcoin")) - suite.defaultDenom = res.GetNewTokenDenom() -} - -func (suite *KeeperTestSuite) TestCreateModuleAccount() { - app := suite.App - - // remove module account - tokenfactoryModuleAccount := app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) - app.AccountKeeper.RemoveAccount(suite.Ctx, tokenfactoryModuleAccount) - - // ensure module account was removed - suite.Ctx = app.BaseApp.NewContext(false, tmproto.Header{}) - tokenfactoryModuleAccount = app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) - suite.Require().Nil(tokenfactoryModuleAccount) - - // create module account - app.TokenFactoryKeeper.CreateModuleAccount(suite.Ctx) - - // check that the module account is now initialized - tokenfactoryModuleAccount = app.AccountKeeper.GetAccount(suite.Ctx, app.AccountKeeper.GetModuleAddress(types.ModuleName)) - suite.Require().NotNil(tokenfactoryModuleAccount) -} diff --git a/x/tokenfactory/keeper/migrations.go b/x/tokenfactory/keeper/migrations.go deleted file mode 100644 index 81b2ba40bd..0000000000 --- a/x/tokenfactory/keeper/migrations.go +++ /dev/null @@ -1,79 +0,0 @@ -package keeper - -import ( - "fmt" - "strings" - - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -const KeySeparator = "|" - -// 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} -} - -// Migrate2to3 migrates from version 2 to 3. -func (m Migrator) Migrate2to3(ctx sdk.Context) error { - // Reset params after removing the denom creation fee param - defaultParams := types.Params{} - m.keeper.paramSpace.SetParamSet(ctx, &defaultParams) - - // We remove the denom creation fee whitelist in this migration - store := ctx.KVStore(m.keeper.storeKey) - oldCreateDenomFeeWhitelistKey := "createdenomfeewhitelist" - - oldCreateDenomFeeWhitelistPrefix := []byte(strings.Join([]string{oldCreateDenomFeeWhitelistKey, ""}, KeySeparator)) - iter := sdk.KVStorePrefixIterator(store, oldCreateDenomFeeWhitelistPrefix) - defer func() { _ = iter.Close() }() - for ; iter.Valid(); iter.Next() { - store.Delete(iter.Key()) - } - return nil -} - -func (m Migrator) Migrate3to4(ctx sdk.Context) error { - // Set denom metadata for all denoms - iter := m.keeper.GetAllDenomsIterator(ctx) - defer func() { _ = iter.Close() }() - for ; iter.Valid(); iter.Next() { - denom := string(iter.Value()) - denomMetadata, found := m.keeper.bankKeeper.GetDenomMetaData(ctx, denom) - if !found { - panic(fmt.Errorf("denom %s does not exist", denom)) - } - fmt.Printf("Migrating denom: %s\n", denom) - m.SetMetadata(&denomMetadata) - m.keeper.bankKeeper.SetDenomMetaData(ctx, denomMetadata) - } - return nil -} - -func (m Migrator) Migrate4to5(ctx sdk.Context) error { - // Add new params and set all to defaults - defaultParams := types.DefaultParams() - m.keeper.SetParams(ctx, defaultParams) - return nil -} - -func (m Migrator) SetMetadata(denomMetadata *banktypes.Metadata) { - if len(denomMetadata.Base) == 0 { - panic(fmt.Errorf("no base exists for denom %v", denomMetadata)) - } - if len(denomMetadata.Display) == 0 { - denomMetadata.Display = denomMetadata.Base - denomMetadata.Name = denomMetadata.Base - denomMetadata.Symbol = denomMetadata.Base - } else { - fmt.Printf("Denom %s already has denom set", denomMetadata.Base) - } -} diff --git a/x/tokenfactory/keeper/migrations_test.go b/x/tokenfactory/keeper/migrations_test.go deleted file mode 100644 index b76f426f45..0000000000 --- a/x/tokenfactory/keeper/migrations_test.go +++ /dev/null @@ -1,130 +0,0 @@ -package keeper - -import ( - "strings" - "testing" - - bankkeeper "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/keeper" - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - - "github.com/sei-protocol/sei-chain/sei-cosmos/codec" - codectypes "github.com/sei-protocol/sei-chain/sei-cosmos/codec/types" - "github.com/sei-protocol/sei-chain/sei-cosmos/store" - storetypes "github.com/sei-protocol/sei-chain/sei-cosmos/store/types" - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - typesparams "github.com/sei-protocol/sei-chain/sei-cosmos/x/params/types" - tmproto "github.com/sei-protocol/sei-chain/sei-tendermint/proto/tendermint/types" - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" - "github.com/stretchr/testify/require" - tmdb "github.com/tendermint/tm-db" -) - -func TestMigrate2to3(t *testing.T) { - storeKey := sdk.NewKVStoreKey(types.StoreKey) - bankstorekey := sdk.NewKVStoreKey(banktypes.StoreKey) - memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) - - db := tmdb.NewMemDB() - stateStore := store.NewCommitMultiStore(db) - stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db) - stateStore.MountStoreWithDB(bankstorekey, sdk.StoreTypeIAVL, db) - stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil) - require.NoError(t, stateStore.LoadLatestVersion()) - - registry := codectypes.NewInterfaceRegistry() - cdc := codec.NewProtoCodec(registry) - - paramsSubspace := typesparams.NewSubspace(cdc, - codec.NewLegacyAmino(), - storeKey, - memStoreKey, - "TokenfactoryParams", - ) - oldCreateDenomFeeWhitelistKey := "createdenomfeewhitelist" - KeySeparator := "|" - - // keys from old denom creation fee whitelist - oldCreateDenomFeeWhitelistPrefix := []byte(strings.Join([]string{oldCreateDenomFeeWhitelistKey, ""}, KeySeparator)) - oldCreatorSpecificPrefix := []byte(strings.Join([]string{oldCreateDenomFeeWhitelistKey, "creator", ""}, KeySeparator)) - - ctx := sdk.NewContext(stateStore, tmproto.Header{}, false) - if !paramsSubspace.HasKeyTable() { - paramsSubspace = paramsSubspace.WithKeyTable(types.ParamKeyTable()) - } - - // Set dummy values for old denom creation whitelist - store := ctx.KVStore(storeKey) - store.Set(oldCreateDenomFeeWhitelistPrefix, []byte("garbage value whitelist")) - store.Set(oldCreatorSpecificPrefix, []byte("garbage value whitelist creator")) - require.True(t, store.Has(oldCreateDenomFeeWhitelistPrefix)) - require.True(t, store.Has(oldCreatorSpecificPrefix)) - newKeeper := NewKeeper(cdc, storeKey, paramsSubspace, nil, bankkeeper.NewBaseKeeper(cdc, bankstorekey, nil, paramsSubspace, nil), nil) - m := NewMigrator(newKeeper) - err := m.Migrate2to3(ctx) - require.Nil(t, err) - require.False(t, store.Has(oldCreateDenomFeeWhitelistPrefix)) - require.False(t, store.Has(oldCreatorSpecificPrefix)) - - // Params should also be empty - params := types.Params{} - paramsSubspace.GetParamSet(ctx, ¶ms) - require.Equal(t, types.Params{}, params) - - m.keeper.addDenomFromCreator(ctx, "creator", "test_denom") - m.keeper.bankKeeper.SetDenomMetaData(ctx, banktypes.Metadata{Base: "test_denom", Name: "test_denom", Symbol: "test_denom"}) - err = m.Migrate3to4(ctx) - require.Nil(t, err) -} - -func TestMigrate3To4(t *testing.T) { - // Test migration with all metadata denom - metadata := banktypes.Metadata{Description: sdk.DefaultBondDenom, Base: sdk.DefaultBondDenom, Display: sdk.DefaultBondDenom, Name: sdk.DefaultBondDenom, Symbol: sdk.DefaultBondDenom} - _, keeper := getStoreAndKeeper(t) - m := NewMigrator(keeper) - m.SetMetadata(&metadata) - require.Equal(t, sdk.DefaultBondDenom, metadata.Display) - require.Equal(t, sdk.DefaultBondDenom, metadata.Name) - require.Equal(t, sdk.DefaultBondDenom, metadata.Symbol) - // Test migration with missing fields - testDenom := "test_denom" - metadata = banktypes.Metadata{Base: testDenom} - m.SetMetadata(&metadata) - require.Equal(t, testDenom, metadata.Display) - require.Equal(t, testDenom, metadata.Name) - require.Equal(t, testDenom, metadata.Symbol) -} - -func TestMigrate4To5(t *testing.T) { - stateStore, keeper := getStoreAndKeeper(t) - m := NewMigrator(keeper) - ctx := sdk.NewContext(stateStore, tmproto.Header{}, false) - err := m.Migrate4to5(ctx) - require.NoError(t, err) - require.NotPanics(t, func() { m.keeper.GetParams(ctx) }) - params := m.keeper.GetParams(ctx) - require.Equal(t, types.DefaultParams(), params) -} - -func getStoreAndKeeper(t *testing.T) (store.CommitMultiStore, Keeper) { - storeKey := sdk.NewKVStoreKey(types.StoreKey) - bankStoreKey := sdk.NewKVStoreKey(banktypes.StoreKey) - memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) - - db := tmdb.NewMemDB() - stateStore := store.NewCommitMultiStore(db) - stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db) - stateStore.MountStoreWithDB(bankStoreKey, sdk.StoreTypeIAVL, db) - stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil) - require.NoError(t, stateStore.LoadLatestVersion()) - - registry := codectypes.NewInterfaceRegistry() - cdc := codec.NewProtoCodec(registry) - - paramsSubspace := typesparams.NewSubspace(cdc, - codec.NewLegacyAmino(), - storeKey, - memStoreKey, - "TokenfactoryParams", - ) - return stateStore, NewKeeper(nil, nil, paramsSubspace, nil, nil, nil) -} diff --git a/x/tokenfactory/keeper/msg_server.go b/x/tokenfactory/keeper/msg_server.go deleted file mode 100644 index 7c98ded3de..0000000000 --- a/x/tokenfactory/keeper/msg_server.go +++ /dev/null @@ -1,217 +0,0 @@ -package keeper - -import ( - "context" - "strings" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -type msgServer struct { - Keeper -} - -// NewMsgServerImpl returns an implementation of the MsgServer interface -// for the provided Keeper. -func NewMsgServerImpl(keeper Keeper) types.MsgServer { - return &msgServer{Keeper: keeper} -} - -var _ types.MsgServer = msgServer{} - -func (server msgServer) CreateDenom(goCtx context.Context, msg *types.MsgCreateDenom) (*types.MsgCreateDenomResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - - denom, err := server.Keeper.CreateDenom(ctx, msg.Sender, msg.Subdenom) - if err != nil { - return nil, err - } - - createDenomEvent := sdk.NewEvent( - types.TypeMsgCreateDenom, - sdk.NewAttribute(types.AttributeCreator, msg.Sender), - sdk.NewAttribute(types.AttributeNewTokenDenom, denom), - ) - - if msg.AllowList != nil { - err = server.validateAllowList(ctx, msg.AllowList) - if err != nil { - return nil, err - } - server.bankKeeper.SetDenomAllowList(ctx, denom, *msg.AllowList) - createDenomEvent = createDenomEvent.AppendAttributes( - sdk.NewAttribute(types.AttributeAllowList, strings.Join(msg.AllowList.Addresses, ",")), - ) - } - - ctx.EventManager().EmitEvents(sdk.Events{ - createDenomEvent, - }) - - return &types.MsgCreateDenomResponse{ - NewTokenDenom: denom, - }, nil -} - -func (server msgServer) UpdateDenom(goCtx context.Context, msg *types.MsgUpdateDenom) (*types.MsgUpdateDenomResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - - denom, err := server.validateUpdateDenom(ctx, msg) - if err != nil { - return nil, err - } - - authorityMetadata, err := server.GetAuthorityMetadata(ctx, denom) - if err != nil { - return nil, err - } - - if msg.Sender != authorityMetadata.GetAdmin() { - return nil, types.ErrUnauthorized - } - - updateDenomEvent := sdk.NewEvent( - types.TypeMsgUpdateDenom, - sdk.NewAttribute(types.AttributeCreator, msg.Sender), - sdk.NewAttribute(types.AttributeUpdatedTokenDenom, denom), - ) - - if msg.AllowList != nil { - server.bankKeeper.SetDenomAllowList(ctx, denom, *msg.AllowList) - updateDenomEvent = updateDenomEvent.AppendAttributes( - sdk.NewAttribute(types.AttributeAllowList, strings.Join(msg.AllowList.Addresses, ",")), - ) - } - - ctx.EventManager().EmitEvents(sdk.Events{ - updateDenomEvent, - }) - - return &types.MsgUpdateDenomResponse{}, nil -} - -func (server msgServer) Mint(goCtx context.Context, msg *types.MsgMint) (*types.MsgMintResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - - // pay some extra gas cost to give a better error here. - _, denomExists := server.bankKeeper.GetDenomMetaData(ctx, msg.Amount.Denom) - if !denomExists { - return nil, types.ErrDenomDoesNotExist.Wrapf("denom: %s", msg.Amount.Denom) - } - - authorityMetadata, err := server.GetAuthorityMetadata(ctx, msg.Amount.GetDenom()) - if err != nil { - return nil, err - } - - if msg.Sender != authorityMetadata.GetAdmin() { - return nil, types.ErrUnauthorized - } - - err = server.mintTo(ctx, msg.Amount, msg.Sender) - if err != nil { - return nil, err - } - - ctx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - types.TypeMsgMint, - sdk.NewAttribute(types.AttributeMintToAddress, msg.Sender), - sdk.NewAttribute(types.AttributeAmount, msg.Amount.String()), - ), - }) - - return &types.MsgMintResponse{}, nil -} - -func (server msgServer) Burn(goCtx context.Context, msg *types.MsgBurn) (*types.MsgBurnResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - - authorityMetadata, err := server.GetAuthorityMetadata(ctx, msg.Amount.GetDenom()) - if err != nil { - return nil, err - } - - if msg.Sender != authorityMetadata.GetAdmin() { - return nil, types.ErrUnauthorized - } - - err = server.burnFrom(ctx, msg.Amount, msg.Sender) - if err != nil { - return nil, err - } - - ctx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - types.TypeMsgBurn, - sdk.NewAttribute(types.AttributeBurnFromAddress, msg.Sender), - sdk.NewAttribute(types.AttributeAmount, msg.Amount.String()), - ), - }) - - return &types.MsgBurnResponse{}, nil -} - -func (server msgServer) ChangeAdmin(goCtx context.Context, msg *types.MsgChangeAdmin) (*types.MsgChangeAdminResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - - authorityMetadata, err := server.GetAuthorityMetadata(ctx, msg.Denom) - if err != nil { - return nil, err - } - - if msg.Sender != authorityMetadata.GetAdmin() { - return nil, types.ErrUnauthorized - } - - // Validate new admin we change to should be different from current admin - if msg.NewAdmin == authorityMetadata.GetAdmin() { - return nil, types.ErrAdminAlreadyExists - } - - err = server.setAdmin(ctx, msg.Denom, msg.NewAdmin) - if err != nil { - return nil, err - } - ctx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - types.TypeMsgChangeAdmin, - sdk.NewAttribute(types.AttributeDenom, msg.GetDenom()), - sdk.NewAttribute(types.AttributeNewAdmin, msg.NewAdmin), - ), - }) - - return &types.MsgChangeAdminResponse{}, nil -} - -func (server msgServer) SetDenomMetadata(goCtx context.Context, msg *types.MsgSetDenomMetadata) (*types.MsgSetDenomMetadataResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - - // Defense in depth validation of metadata - err := msg.Metadata.Validate() - if err != nil { - return nil, err - } - - authorityMetadata, err := server.GetAuthorityMetadata(ctx, msg.Metadata.Base) - if err != nil { - return nil, err - } - - if msg.Sender != authorityMetadata.GetAdmin() { - return nil, types.ErrUnauthorized - } - - server.bankKeeper.SetDenomMetaData(ctx, msg.Metadata) - - ctx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - types.TypeMsgSetDenomMetadata, - sdk.NewAttribute(types.AttributeDenom, msg.Metadata.Base), - sdk.NewAttribute(types.AttributeDenomMetadata, msg.Metadata.String()), - ), - }) - - return &types.MsgSetDenomMetadataResponse{}, nil -} diff --git a/x/tokenfactory/keeper/params.go b/x/tokenfactory/keeper/params.go deleted file mode 100644 index 6be72cd586..0000000000 --- a/x/tokenfactory/keeper/params.go +++ /dev/null @@ -1,18 +0,0 @@ -package keeper - -import ( - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" -) - -// GetParams returns the total set params. -func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { - k.paramSpace.GetParamSet(ctx, ¶ms) - return params -} - -// SetParams sets the total set of params. -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { - k.paramSpace.SetParamSet(ctx, ¶ms) -} diff --git a/x/tokenfactory/module.go b/x/tokenfactory/module.go deleted file mode 100644 index b9b85f56b7..0000000000 --- a/x/tokenfactory/module.go +++ /dev/null @@ -1,170 +0,0 @@ -/* -The tokenfactory module allows any account to create a new token with -the name `factory/{creator address}/{subdenom}`. - -- Mint and burn user denom to and form any account -- Create a transfer of their denom between any two accounts -- Change the admin. In the future, more admin capabilities may be added. -*/ -package tokenfactory - -import ( - "context" - "encoding/json" - "fmt" - - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/sei-protocol/sei-chain/sei-cosmos/client" - "github.com/sei-protocol/sei-chain/sei-cosmos/codec" - cdctypes "github.com/sei-protocol/sei-chain/sei-cosmos/codec/types" - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - "github.com/sei-protocol/sei-chain/sei-cosmos/types/module" - abci "github.com/sei-protocol/sei-chain/sei-tendermint/abci/types" - "github.com/spf13/cobra" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/client/cli" - "github.com/sei-protocol/sei-chain/x/tokenfactory/keeper" - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} -) - -// AppModuleBasic implements the AppModuleBasic interface for the capability module. -type AppModuleBasic struct{} - -func NewAppModuleBasic() AppModuleBasic { - return AppModuleBasic{} -} - -// Name returns the x/tokenfactory module's name. -func (AppModuleBasic) Name() string { - return types.ModuleName -} - -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { - types.RegisterCodec(cdc) -} - -// RegisterInterfaces registers the module's interface types -func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { - types.RegisterInterfaces(reg) -} - -// DefaultGenesis returns the x/tokenfactory module's default genesis state. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return cdc.MustMarshalJSON(types.DefaultGenesis()) -} - -// ValidateGenesis performs genesis state validation for the x/tokenfactory module. -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { - var genState types.GenesisState - if err := cdc.UnmarshalAsJSON(bz, &genState); err != nil { - return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) - } - - return genState.Validate() -} - -// RegisterRESTRoutes registers the capability module's REST service handlers. -func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) { -} - -// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - _ = types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) -} - -// GetTxCmd returns the x/tokenfactory module's root tx command. -func (a AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.GetTxCmd() -} - -// GetQueryCmd returns the x/tokenfactory module's root query command. -func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd() -} - -// AppModule implements the AppModule interface for the capability module. -type AppModule struct { - AppModuleBasic - - keeper keeper.Keeper - accountKeeper types.AccountKeeper - bankKeeper types.BankKeeper -} - -func NewAppModule( - keeper keeper.Keeper, - accountKeeper types.AccountKeeper, - bankKeeper types.BankKeeper, -) AppModule { - return AppModule{ - AppModuleBasic: NewAppModuleBasic(), - keeper: keeper, - accountKeeper: accountKeeper, - bankKeeper: bankKeeper, - } -} - -// Name returns the x/tokenfactory module's name. -func (am AppModule) Name() string { - return am.AppModuleBasic.Name() -} - -// Route returns the x/tokenfactory module's message routing key. -func (am AppModule) Route() sdk.Route { - return sdk.Route{} -} - -// QuerierRoute returns the x/tokenfactory module's query routing key. -func (AppModule) QuerierRoute() string { return types.QuerierRoute } - -// LegacyQuerierHandler returns the x/tokenfactory module's Querier. -func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { - return nil -} - -// RegisterServices registers a GRPC query service to respond to the -// module-specific GRPC queries. -func (am AppModule) RegisterServices(cfg module.Configurator) { - types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) - types.RegisterQueryServer(cfg.QueryServer(), am.keeper) - - m := keeper.NewMigrator(am.keeper) - _ = cfg.RegisterMigration(types.ModuleName, 1, func(ctx sdk.Context) error { return nil }) - _ = cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3) - _ = cfg.RegisterMigration(types.ModuleName, 3, m.Migrate3to4) - _ = cfg.RegisterMigration(types.ModuleName, 4, m.Migrate4to5) -} - -// RegisterInvariants registers the x/tokenfactory module's invariants. -func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} - -// InitGenesis performs the x/tokenfactory module's genesis initialization. It -// returns no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { - var genState types.GenesisState - cdc.MustUnmarshalJSON(gs, &genState) - - am.keeper.InitGenesis(ctx, genState) - - return []abci.ValidatorUpdate{} -} - -// ValidateGenesisStream performs genesis state validation for the x/tokenfactory module in a streaming fashion. -func (am AppModuleBasic) ValidateGenesisStream(cdc codec.JSONCodec, config client.TxEncodingConfig, genesisCh <-chan json.RawMessage) error { - for genesis := range genesisCh { - err := am.ValidateGenesis(cdc, config, genesis) - if err != nil { - return err - } - } - return nil -} - -// ConsensusVersion implements ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 5 } diff --git a/x/tokenfactory/types/authority_metadata.go b/x/tokenfactory/types/authority_metadata.go deleted file mode 100644 index 9da0fb1854..0000000000 --- a/x/tokenfactory/types/authority_metadata.go +++ /dev/null @@ -1,15 +0,0 @@ -package types - -import ( - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" -) - -func (metadata DenomAuthorityMetadata) Validate() error { - if metadata.Admin != "" { - _, err := sdk.AccAddressFromBech32(metadata.Admin) - if err != nil { - return err - } - } - return nil -} diff --git a/x/tokenfactory/types/authority_metadata.pb.go b/x/tokenfactory/types/authority_metadata.pb.go deleted file mode 100644 index 4cb4dbe617..0000000000 --- a/x/tokenfactory/types/authority_metadata.pb.go +++ /dev/null @@ -1,349 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: tokenfactory/authority_metadata.proto - -package types - -import ( - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// 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 - -// 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. -type DenomAuthorityMetadata struct { - // Can be empty for no admin, or a valid sei address - Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty" yaml:"admin"` -} - -func (m *DenomAuthorityMetadata) Reset() { *m = DenomAuthorityMetadata{} } -func (m *DenomAuthorityMetadata) String() string { return proto.CompactTextString(m) } -func (*DenomAuthorityMetadata) ProtoMessage() {} -func (*DenomAuthorityMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_2e0fb97022669b8a, []int{0} -} -func (m *DenomAuthorityMetadata) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *DenomAuthorityMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_DenomAuthorityMetadata.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 *DenomAuthorityMetadata) XXX_Merge(src proto.Message) { - xxx_messageInfo_DenomAuthorityMetadata.Merge(m, src) -} -func (m *DenomAuthorityMetadata) XXX_Size() int { - return m.Size() -} -func (m *DenomAuthorityMetadata) XXX_DiscardUnknown() { - xxx_messageInfo_DenomAuthorityMetadata.DiscardUnknown(m) -} - -var xxx_messageInfo_DenomAuthorityMetadata proto.InternalMessageInfo - -func (m *DenomAuthorityMetadata) GetAdmin() string { - if m != nil { - return m.Admin - } - return "" -} - -func init() { - proto.RegisterType((*DenomAuthorityMetadata)(nil), "seiprotocol.seichain.tokenfactory.DenomAuthorityMetadata") -} - -func init() { - proto.RegisterFile("tokenfactory/authority_metadata.proto", fileDescriptor_2e0fb97022669b8a) -} - -var fileDescriptor_2e0fb97022669b8a = []byte{ - // 215 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x2d, 0xc9, 0xcf, 0x4e, - 0xcd, 0x4b, 0x4b, 0x4c, 0x2e, 0xc9, 0x2f, 0xaa, 0xd4, 0x4f, 0x2c, 0x2d, 0xc9, 0xc8, 0x2f, 0xca, - 0x2c, 0xa9, 0x8c, 0xcf, 0x4d, 0x2d, 0x49, 0x4c, 0x49, 0x2c, 0x49, 0xd4, 0x2b, 0x28, 0xca, 0x2f, - 0xc9, 0x17, 0x52, 0x2c, 0x4e, 0xcd, 0x04, 0xb3, 0x92, 0xf3, 0x73, 0xf4, 0x8a, 0x53, 0x33, 0x93, - 0x33, 0x12, 0x33, 0xf3, 0xf4, 0x90, 0xf5, 0x4a, 0x89, 0xa4, 0xe7, 0xa7, 0xe7, 0x83, 0xd5, 0xe8, - 0x83, 0x58, 0x10, 0x8d, 0x4a, 0x6e, 0x5c, 0x62, 0x2e, 0xa9, 0x79, 0xf9, 0xb9, 0x8e, 0x30, 0x93, - 0x7d, 0xa1, 0x06, 0x0b, 0xa9, 0x71, 0xb1, 0x26, 0xa6, 0xe4, 0x66, 0xe6, 0x49, 0x30, 0x2a, 0x30, - 0x6a, 0x70, 0x3a, 0x09, 0x7c, 0xba, 0x27, 0xcf, 0x53, 0x99, 0x98, 0x9b, 0x63, 0xa5, 0x04, 0x16, - 0x56, 0x0a, 0x82, 0x48, 0x5b, 0xb1, 0xbc, 0x58, 0x20, 0xcf, 0xe8, 0x14, 0x70, 0xe2, 0x91, 0x1c, - 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, - 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x66, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, - 0xf9, 0xb9, 0xfa, 0xc5, 0xa9, 0x99, 0xba, 0x30, 0x67, 0x82, 0x39, 0x60, 0x77, 0xea, 0x57, 0xe8, - 0xa3, 0xf8, 0xb2, 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0xac, 0xd0, 0x18, 0x30, 0x00, 0xd4, - 0x4d, 0xde, 0xdb, 0x02, 0x01, 0x00, 0x00, -} - -func (this *DenomAuthorityMetadata) Equal(that interface{}) bool { - if that == nil { - return this == nil - } - - that1, ok := that.(*DenomAuthorityMetadata) - if !ok { - that2, ok := that.(DenomAuthorityMetadata) - if ok { - that1 = &that2 - } else { - return false - } - } - if that1 == nil { - return this == nil - } else if this == nil { - return false - } - if this.Admin != that1.Admin { - return false - } - return true -} -func (m *DenomAuthorityMetadata) 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 *DenomAuthorityMetadata) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *DenomAuthorityMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Admin) > 0 { - i -= len(m.Admin) - copy(dAtA[i:], m.Admin) - i = encodeVarintAuthorityMetadata(dAtA, i, uint64(len(m.Admin))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintAuthorityMetadata(dAtA []byte, offset int, v uint64) int { - offset -= sovAuthorityMetadata(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *DenomAuthorityMetadata) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Admin) - if l > 0 { - n += 1 + l + sovAuthorityMetadata(uint64(l)) - } - return n -} - -func sovAuthorityMetadata(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozAuthorityMetadata(x uint64) (n int) { - return sovAuthorityMetadata(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *DenomAuthorityMetadata) 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 ErrIntOverflowAuthorityMetadata - } - 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: DenomAuthorityMetadata: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DenomAuthorityMetadata: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Admin", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthorityMetadata - } - 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 ErrInvalidLengthAuthorityMetadata - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAuthorityMetadata - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Admin = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAuthorityMetadata(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAuthorityMetadata - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipAuthorityMetadata(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, ErrIntOverflowAuthorityMetadata - } - 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, ErrIntOverflowAuthorityMetadata - } - 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, ErrIntOverflowAuthorityMetadata - } - 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, ErrInvalidLengthAuthorityMetadata - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupAuthorityMetadata - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthAuthorityMetadata - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthAuthorityMetadata = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowAuthorityMetadata = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupAuthorityMetadata = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/tokenfactory/types/denoms.go b/x/tokenfactory/types/denoms.go deleted file mode 100644 index b869dbbd81..0000000000 --- a/x/tokenfactory/types/denoms.go +++ /dev/null @@ -1,84 +0,0 @@ -package types - -import ( - fmt "fmt" - "strings" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - sdkerrors "github.com/sei-protocol/sei-chain/sei-cosmos/types/errors" - bankkeeper "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/keeper" -) - -const ( - ModuleDenomPrefix = "factory" - // See the TokenFactory readme for a derivation of these. - // TL;DR, MaxSubdenomLength + MaxHrpLength = 60 comes from SDK max denom length = 128 - // and the structure of tokenfactory denoms. - MaxSubdenomLength = 44 - MaxHrpLength = 16 - // MaxCreatorLength = 59 + MaxHrpLength - MaxCreatorLength = 59 + MaxHrpLength -) - -// GetTokenDenom constructs a denom string for tokens created by tokenfactory -// based on an input creator address and a subdenom -// The denom constructed is factory/{creator}/{subdenom} -func GetTokenDenom(creator, subdenom string) (string, error) { - if len(subdenom) > MaxSubdenomLength { - return "", ErrSubdenomTooLong - } - if len(creator) > MaxCreatorLength { - return "", ErrCreatorTooLong - } - if strings.Contains(creator, "/") { - return "", ErrInvalidCreator - } - denom := strings.Join([]string{ModuleDenomPrefix, creator, subdenom}, "/") - return denom, sdk.ValidateDenom(denom) -} - -// DeconstructDenom takes a token denom string and verifies that it is a valid -// denom of the tokenfactory module, and is of the form `factory/{creator}/{subdenom}` -// If valid, it returns the creator address and subdenom -func DeconstructDenom(denom string) (creator string, subdenom string, err error) { - err = sdk.ValidateDenom(denom) - if err != nil { - return "", "", err - } - - strParts := strings.Split(denom, "/") - if len(strParts) < 3 { - return "", "", sdkerrors.Wrapf(ErrInvalidDenom, "not enough parts of denom %s", denom) - } - - if strParts[0] != ModuleDenomPrefix { - return "", "", sdkerrors.Wrapf(ErrInvalidDenom, "denom prefix is incorrect. Is: %s. Should be: %s", strParts[0], ModuleDenomPrefix) - } - - creator = strParts[1] - _, err = sdk.AccAddressFromBech32(creator) - if err != nil { - return "", "", sdkerrors.Wrapf(ErrInvalidDenom, "Invalid creator address (%s)", err) - } - - // Handle the case where a denom has a slash in its subdenom. For example, - // when we did the split, we'd turn factory/accaddr/atomderivative/sikka into ["factory", "accaddr", "atomderivative", "sikka"] - // So we have to join [2:] with a "/" as the delimiter to get back the correct subdenom which should be "atomderivative/sikka" - subdenom = strings.Join(strParts[2:], "/") - - return creator, subdenom, nil -} - -// NewTokenFactoryDenomMintCoinsRestriction creates and returns a BankMintingRestrictionFn that only allows minting of -// valid tokenfactory denoms -func NewTokenFactoryDenomMintCoinsRestriction() bankkeeper.MintingRestrictionFn { - return func(ctx sdk.Context, coinsToMint sdk.Coins) error { - for _, coin := range coinsToMint { - _, _, err := DeconstructDenom(coin.Denom) - if err != nil { - return fmt.Errorf("does not have permission to mint %s", coin.Denom) - } - } - return nil - } -} diff --git a/x/tokenfactory/types/denoms_test.go b/x/tokenfactory/types/denoms_test.go deleted file mode 100644 index 49a51f1daa..0000000000 --- a/x/tokenfactory/types/denoms_test.go +++ /dev/null @@ -1,153 +0,0 @@ -package types_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - appparams "github.com/sei-protocol/sei-chain/app/params" - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -func TestDecomposeDenoms(t *testing.T) { - appparams.SetAddressPrefixes() - for _, tc := range []struct { - desc string - denom string - valid bool - }{ - { - desc: "empty is invalid", - denom: "", - valid: false, - }, - { - desc: "normal", - denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/bitcoin", - valid: true, - }, - { - desc: "multiple slashes in subdenom", - denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/bitcoin/1", - valid: true, - }, - { - desc: "no subdenom", - denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/", - valid: true, - }, - { - desc: "incorrect prefix", - denom: "ibc/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/bitcoin", - valid: false, - }, - { - desc: "subdenom of only slashes", - denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/////", - valid: true, - }, - { - desc: "too long name", - denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/adsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsf", - valid: false, - }, - { - desc: "too long creator name", - denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjwasdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfas/bitcoin", - valid: false, - }, - { - desc: "empty subdenom", - denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/", - valid: true, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - _, _, err := types.DeconstructDenom(tc.denom) - if tc.valid { - require.NoError(t, err) - } else { - require.Error(t, err) - } - }) - } -} - -func TestGetTokenDenom(t *testing.T) { - for _, tc := range []struct { - desc string - creator string - subdenom string - valid bool - }{ - { - desc: "normal", - creator: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - subdenom: "bitcoin", - valid: true, - }, - { - desc: "multiple slashes in subdenom", - creator: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - subdenom: "bitcoin/1", - valid: true, - }, - { - desc: "no subdenom", - creator: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - subdenom: "", - valid: true, - }, - { - desc: "subdenom of only slashes", - creator: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - subdenom: "/////", - valid: true, - }, - { - desc: "too long name", - creator: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - subdenom: "adsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsfadsf", - valid: false, - }, - { - desc: "subdenom is exactly max length", - creator: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - subdenom: "bitcoinfsadfsdfeadfsafwefsefsefsdfsdafasefsf", - valid: true, - }, - { - desc: "creator is exactly max length", - creator: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjwhjkljkljkljkljkljkljkljkljkljkljk", - subdenom: "bitcoin", - valid: true, - }, - { - desc: "empty subdenom", - creator: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - subdenom: "", - valid: true, - }, - { - desc: "non standard UTF-8", - creator: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - subdenom: "\u2603", - valid: false, - }, - { - desc: "non standard ASCII", - creator: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - subdenom: "\n\t", - valid: false, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - _, err := types.GetTokenDenom(tc.creator, tc.subdenom) - if tc.valid { - require.NoError(t, err) - } else { - require.Error(t, err) - } - }) - } -} diff --git a/x/tokenfactory/types/errors.go b/x/tokenfactory/types/errors.go deleted file mode 100644 index 780e5685bd..0000000000 --- a/x/tokenfactory/types/errors.go +++ /dev/null @@ -1,34 +0,0 @@ -package types - -// DONTCOVER - -import ( - fmt "fmt" - - sdkerrors "github.com/sei-protocol/sei-chain/sei-cosmos/types/errors" -) - -// x/tokenfactory module sentinel errors -var ( - ErrDenomExists = sdkerrors.Register(ModuleName, 2, "attempting to create a denom that already exists (has bank metadata)") - ErrUnauthorized = sdkerrors.Register(ModuleName, 3, "unauthorized account") - ErrInvalidDenom = sdkerrors.Register(ModuleName, 4, "invalid denom") - ErrInvalidCreator = sdkerrors.Register(ModuleName, 5, "invalid creator") - ErrInvalidAuthorityMetadata = sdkerrors.Register(ModuleName, 6, "invalid authority metadata") - ErrInvalidGenesis = sdkerrors.Register(ModuleName, 7, "invalid genesis") - ErrSubdenomTooLong = sdkerrors.Register(ModuleName, 8, fmt.Sprintf("subdenom too long, max length is %d bytes", MaxSubdenomLength)) - ErrCreatorTooLong = sdkerrors.Register(ModuleName, 9, fmt.Sprintf("creator too long, max length is %d bytes", MaxCreatorLength)) - ErrDenomDoesNotExist = sdkerrors.Register(ModuleName, 10, "denom does not exist") - ErrEncodeTokenFactoryCreateDenom = sdkerrors.Register(ModuleName, 11, "Error while encoding tokenfactory create denom msg in wasmd") - ErrEncodeTokenFactoryMint = sdkerrors.Register(ModuleName, 12, "Error while encoding tokenfactory mint denom msg in wasmd") - ErrEncodeTokenFactoryBurn = sdkerrors.Register(ModuleName, 13, "Error while encoding tokenfactory burn denom msg in wasmd") - ErrEncodeTokenFactoryChangeAdmin = sdkerrors.Register(ModuleName, 14, "Error while encoding tokenfactory change admin msg in wasmd") - ErrParsingSeiTokenFactoryQuery = sdkerrors.Register(ModuleName, 15, "Error parsing SeiTokenFactoryQuery") - ErrAdminAlreadyExists = sdkerrors.Register(ModuleName, 16, "attempting to create a new admin that already exists for the denom") - ErrEncodeTokenFactorySetMetadata = sdkerrors.Register(ModuleName, 17, "Error while encoding tokenfactory set metadata msg in wasmd") - ErrEncodingDenomAuthorityMetadata = sdkerrors.Register(ModuleName, 18, "Error encoding denom authority metadata as JSON") - ErrEncodingDenomsFromCreator = sdkerrors.Register(ModuleName, 19, "Error encoding denoms from creator as JSON") - ErrUnknownSeiTokenFactoryQuery = sdkerrors.Register(ModuleName, 23, "Error unknown sei token factory query") - ErrAllowListTooLarge = sdkerrors.Register(ModuleName, 24, "allowlist too large") - ErrAllowListUndefined = sdkerrors.Register(ModuleName, 25, "allowlist undefined") -) diff --git a/x/tokenfactory/types/events.go b/x/tokenfactory/types/events.go deleted file mode 100644 index 20b4e0da55..0000000000 --- a/x/tokenfactory/types/events.go +++ /dev/null @@ -1,19 +0,0 @@ -package types - -// event types -// nolint -const ( - AttributeAmount = "amount" - AttributeCreator = "creator" - AttributeSubdenom = "subdenom" - AttributeNewTokenDenom = "new_token_denom" //nolint:gosec - AttributeUpdatedTokenDenom = "updated_token_denom" - AttributeMintToAddress = "mint_to_address" - AttributeBurnFromAddress = "burn_from_address" - AttributeTransferFromAddress = "transfer_from_address" - AttributeTransferToAddress = "transfer_to_address" - AttributeDenom = "denom" - AttributeNewAdmin = "new_admin" - AttributeDenomMetadata = "denom_metadata" - AttributeAllowList = "denom_allow_list" -) diff --git a/x/tokenfactory/types/expected_keepers.go b/x/tokenfactory/types/expected_keepers.go deleted file mode 100644 index 94ab18dbc1..0000000000 --- a/x/tokenfactory/types/expected_keepers.go +++ /dev/null @@ -1,42 +0,0 @@ -package types - -import ( - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - authtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/auth/types" - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" -) - -type BankKeeper interface { - // Methods imported from bank should be defined here - GetDenomMetaData(ctx sdk.Context, denom string) (banktypes.Metadata, bool) - SetDenomMetaData(ctx sdk.Context, denomMetaData banktypes.Metadata) - - SetDenomAllowList(ctx sdk.Context, denom string, allowList banktypes.AllowList) - GetDenomAllowList(ctx sdk.Context, denom string) banktypes.AllowList - - HasSupply(ctx sdk.Context, denom string) bool - IterateTotalSupply(ctx sdk.Context, cb func(sdk.Coin) bool) - - SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error - SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error - - DeferredSendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error - - DelegateCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error - UndelegateCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error - MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error - BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error - - SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error -} - -type AccountKeeper interface { - GetModuleAddress(name string) sdk.AccAddress - SetModuleAccount(ctx sdk.Context, macc authtypes.ModuleAccountI) - GetAccount(sdk.Context, sdk.AccAddress) authtypes.AccountI -} - -// DistrKeeper defines the contract needed to be fulfilled for distribution keeper. -type DistrKeeper interface { - FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error -} diff --git a/x/tokenfactory/types/genesis.go b/x/tokenfactory/types/genesis.go deleted file mode 100644 index d4ffa80c83..0000000000 --- a/x/tokenfactory/types/genesis.go +++ /dev/null @@ -1,51 +0,0 @@ -package types - -import ( - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - sdkerrors "github.com/sei-protocol/sei-chain/sei-cosmos/types/errors" -) - -// this line is used by starport scaffolding # genesis/types/import - -// DefaultIndex is the default capability global index -const DefaultIndex uint64 = 1 - -// DefaultGenesis returns the default Capability genesis state -func DefaultGenesis() *GenesisState { - return &GenesisState{ - Params: DefaultParams(), - FactoryDenoms: []GenesisDenom{}, - } -} - -// Validate performs basic genesis state validation returning an error upon any -// failure. -func (gs GenesisState) Validate() error { - err := gs.Params.Validate() - if err != nil { - return err - } - - seenDenoms := map[string]bool{} - - for _, denom := range gs.GetFactoryDenoms() { - if seenDenoms[denom.GetDenom()] { - return sdkerrors.Wrapf(ErrInvalidGenesis, "duplicate denom: %s", denom.GetDenom()) - } - seenDenoms[denom.GetDenom()] = true - - _, _, err := DeconstructDenom(denom.GetDenom()) - if err != nil { - return err - } - - if denom.AuthorityMetadata.Admin != "" { - _, err = sdk.AccAddressFromBech32(denom.AuthorityMetadata.Admin) - if err != nil { - return sdkerrors.Wrapf(ErrInvalidAuthorityMetadata, "Invalid admin address (%s)", err) - } - } - } - - return nil -} diff --git a/x/tokenfactory/types/genesis.pb.go b/x/tokenfactory/types/genesis.pb.go deleted file mode 100644 index ce41217aaf..0000000000 --- a/x/tokenfactory/types/genesis.pb.go +++ /dev/null @@ -1,647 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: tokenfactory/genesis.proto - -package types - -import ( - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// 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 - -// GenesisState defines the tokenfactory module's genesis state. -type GenesisState struct { - // params defines the paramaters of the module. - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - FactoryDenoms []GenesisDenom `protobuf:"bytes,2,rep,name=factory_denoms,json=factoryDenoms,proto3" json:"factory_denoms" yaml:"factory_denoms"` -} - -func (m *GenesisState) Reset() { *m = GenesisState{} } -func (m *GenesisState) String() string { return proto.CompactTextString(m) } -func (*GenesisState) ProtoMessage() {} -func (*GenesisState) Descriptor() ([]byte, []int) { - return fileDescriptor_415d5acd9b7bd461, []int{0} -} -func (m *GenesisState) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_GenesisState.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 *GenesisState) XXX_Merge(src proto.Message) { - xxx_messageInfo_GenesisState.Merge(m, src) -} -func (m *GenesisState) XXX_Size() int { - return m.Size() -} -func (m *GenesisState) XXX_DiscardUnknown() { - xxx_messageInfo_GenesisState.DiscardUnknown(m) -} - -var xxx_messageInfo_GenesisState proto.InternalMessageInfo - -func (m *GenesisState) GetParams() Params { - if m != nil { - return m.Params - } - return Params{} -} - -func (m *GenesisState) GetFactoryDenoms() []GenesisDenom { - if m != nil { - return m.FactoryDenoms - } - return nil -} - -// GenesisDenom defines a tokenfactory denom that is defined within genesis -// state. The structure contains DenomAuthorityMetadata which defines the -// denom's admin. -type GenesisDenom struct { - Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty" yaml:"denom"` - AuthorityMetadata DenomAuthorityMetadata `protobuf:"bytes,2,opt,name=authority_metadata,json=authorityMetadata,proto3" json:"authority_metadata" yaml:"authority_metadata"` -} - -func (m *GenesisDenom) Reset() { *m = GenesisDenom{} } -func (m *GenesisDenom) String() string { return proto.CompactTextString(m) } -func (*GenesisDenom) ProtoMessage() {} -func (*GenesisDenom) Descriptor() ([]byte, []int) { - return fileDescriptor_415d5acd9b7bd461, []int{1} -} -func (m *GenesisDenom) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *GenesisDenom) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_GenesisDenom.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 *GenesisDenom) XXX_Merge(src proto.Message) { - xxx_messageInfo_GenesisDenom.Merge(m, src) -} -func (m *GenesisDenom) XXX_Size() int { - return m.Size() -} -func (m *GenesisDenom) XXX_DiscardUnknown() { - xxx_messageInfo_GenesisDenom.DiscardUnknown(m) -} - -var xxx_messageInfo_GenesisDenom proto.InternalMessageInfo - -func (m *GenesisDenom) GetDenom() string { - if m != nil { - return m.Denom - } - return "" -} - -func (m *GenesisDenom) GetAuthorityMetadata() DenomAuthorityMetadata { - if m != nil { - return m.AuthorityMetadata - } - return DenomAuthorityMetadata{} -} - -func init() { - proto.RegisterType((*GenesisState)(nil), "seiprotocol.seichain.tokenfactory.GenesisState") - proto.RegisterType((*GenesisDenom)(nil), "seiprotocol.seichain.tokenfactory.GenesisDenom") -} - -func init() { proto.RegisterFile("tokenfactory/genesis.proto", fileDescriptor_415d5acd9b7bd461) } - -var fileDescriptor_415d5acd9b7bd461 = []byte{ - // 358 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x51, 0x4f, 0x4b, 0x32, 0x41, - 0x18, 0xdf, 0xf1, 0xf5, 0x15, 0x5a, 0x2d, 0x6a, 0x29, 0x50, 0xa1, 0x5d, 0x5d, 0x28, 0xec, 0xd0, - 0x0e, 0x18, 0x04, 0x79, 0x6b, 0x11, 0x3c, 0x05, 0xb2, 0xdd, 0xba, 0xc8, 0xb8, 0x4e, 0xeb, 0x90, - 0xbb, 0x23, 0x3b, 0x23, 0xb4, 0x9f, 0xa1, 0x4b, 0x1f, 0xa1, 0x8f, 0x23, 0x1d, 0xc2, 0x63, 0x27, - 0x09, 0xbd, 0x74, 0xf6, 0x13, 0xc4, 0xce, 0x8c, 0xd4, 0xe6, 0x21, 0x6f, 0xf3, 0x3c, 0xcf, 0xef, - 0xdf, 0xf3, 0x8c, 0x5e, 0xe5, 0xf4, 0x01, 0x47, 0xf7, 0xc8, 0xe7, 0x34, 0x4e, 0x60, 0x80, 0x23, - 0xcc, 0x08, 0x73, 0xc6, 0x31, 0xe5, 0xd4, 0xa8, 0x33, 0x4c, 0xc4, 0xcb, 0xa7, 0x23, 0x87, 0x61, - 0xe2, 0x0f, 0x11, 0x89, 0x9c, 0x9f, 0x84, 0xea, 0x61, 0x40, 0x03, 0x2a, 0x30, 0x30, 0x7d, 0x49, - 0x62, 0xf5, 0x24, 0x23, 0x8a, 0x26, 0x7c, 0x48, 0x63, 0xc2, 0x93, 0x5e, 0x88, 0x39, 0x1a, 0x20, - 0x8e, 0x14, 0xac, 0x92, 0x81, 0x8d, 0x51, 0x8c, 0x42, 0x65, 0x6d, 0xbf, 0x01, 0xbd, 0xd4, 0x91, - 0x61, 0x6e, 0x39, 0xe2, 0xd8, 0xe8, 0xe8, 0x05, 0x09, 0x28, 0x83, 0x1a, 0x68, 0x14, 0x9b, 0x67, - 0xce, 0x9f, 0xe1, 0x9c, 0xae, 0x20, 0xb8, 0xf9, 0xe9, 0xdc, 0xd2, 0x3c, 0x45, 0x37, 0x26, 0xfa, - 0x9e, 0x9a, 0xf7, 0x06, 0x38, 0xa2, 0x21, 0x2b, 0xe7, 0x6a, 0xff, 0x1a, 0xc5, 0x26, 0xdc, 0x42, - 0x50, 0x25, 0x6a, 0xa7, 0x3c, 0xf7, 0x38, 0x95, 0x5d, 0xcd, 0xad, 0xa3, 0x04, 0x85, 0xa3, 0x96, - 0x9d, 0x15, 0xb5, 0xbd, 0x5d, 0xd5, 0x68, 0xcb, 0xfa, 0xf5, 0x7b, 0x21, 0xd1, 0x31, 0x4e, 0xf5, - 0xff, 0x02, 0x2a, 0xf6, 0xd9, 0x71, 0xf7, 0x57, 0x73, 0xab, 0x24, 0x95, 0x44, 0xdb, 0xf6, 0xe4, - 0xd8, 0x78, 0x02, 0xba, 0xb1, 0x79, 0xc1, 0x72, 0x4e, 0x5c, 0xe1, 0x6a, 0x8b, 0xd0, 0xc2, 0xee, - 0x7a, 0xad, 0x70, 0xa3, 0x04, 0xdc, 0xba, 0x8a, 0x5f, 0x91, 0xa6, 0x9b, 0x16, 0xb6, 0x77, 0x80, - 0x7e, 0xb3, 0x5a, 0xf9, 0xcf, 0x17, 0x0b, 0xb8, 0xdd, 0xe9, 0xc2, 0x04, 0xb3, 0x85, 0x09, 0x3e, - 0x16, 0x26, 0x78, 0x5e, 0x9a, 0xda, 0x6c, 0x69, 0x6a, 0xef, 0x4b, 0x53, 0xbb, 0xbb, 0x0c, 0x08, - 0x1f, 0x4e, 0xfa, 0x8e, 0x4f, 0x43, 0xc8, 0x30, 0x39, 0x5f, 0x67, 0x13, 0x85, 0x08, 0x07, 0x1f, - 0x61, 0xe6, 0xdb, 0x79, 0x32, 0xc6, 0xac, 0x5f, 0x10, 0xc0, 0x8b, 0xaf, 0x01, 0x00, 0x0f, 0xe2, - 0xdb, 0xfc, 0x8f, 0x02, 0x00, 0x00, -} - -func (this *GenesisDenom) Equal(that interface{}) bool { - if that == nil { - return this == nil - } - - that1, ok := that.(*GenesisDenom) - if !ok { - that2, ok := that.(GenesisDenom) - if ok { - that1 = &that2 - } else { - return false - } - } - if that1 == nil { - return this == nil - } else if this == nil { - return false - } - if this.Denom != that1.Denom { - return false - } - if !this.AuthorityMetadata.Equal(&that1.AuthorityMetadata) { - return false - } - return true -} -func (m *GenesisState) 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 *GenesisState) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.FactoryDenoms) > 0 { - for iNdEx := len(m.FactoryDenoms) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.FactoryDenoms[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *GenesisDenom) 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 *GenesisDenom) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *GenesisDenom) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.AuthorityMetadata.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - if len(m.Denom) > 0 { - i -= len(m.Denom) - copy(dAtA[i:], m.Denom) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Denom))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { - offset -= sovGenesis(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *GenesisState) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovGenesis(uint64(l)) - if len(m.FactoryDenoms) > 0 { - for _, e := range m.FactoryDenoms { - l = e.Size() - n += 1 + l + sovGenesis(uint64(l)) - } - } - return n -} - -func (m *GenesisDenom) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Denom) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = m.AuthorityMetadata.Size() - n += 1 + l + sovGenesis(uint64(l)) - return n -} - -func sovGenesis(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenesis(x uint64) (n int) { - return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *GenesisState) 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 ErrIntOverflowGenesis - } - 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: GenesisState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FactoryDenoms", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.FactoryDenoms = append(m.FactoryDenoms, GenesisDenom{}) - if err := m.FactoryDenoms[len(m.FactoryDenoms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *GenesisDenom) 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 ErrIntOverflowGenesis - } - 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: GenesisDenom: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: GenesisDenom: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Denom = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AuthorityMetadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.AuthorityMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipGenesis(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, ErrIntOverflowGenesis - } - 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, ErrIntOverflowGenesis - } - 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, ErrIntOverflowGenesis - } - 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, ErrInvalidLengthGenesis - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupGenesis - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthGenesis - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/tokenfactory/types/genesis_test.go b/x/tokenfactory/types/genesis_test.go deleted file mode 100644 index fedc5531dc..0000000000 --- a/x/tokenfactory/types/genesis_test.go +++ /dev/null @@ -1,139 +0,0 @@ -package types_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" -) - -func TestGenesisState_Validate(t *testing.T) { - for _, tc := range []struct { - desc string - genState *types.GenesisState - valid bool - }{ - { - desc: "default is valid", - genState: types.DefaultGenesis(), - valid: true, - }, - { - desc: "valid genesis state", - genState: &types.GenesisState{ - FactoryDenoms: []types.GenesisDenom{ - { - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/bitcoin", - AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw", - }, - }, - }, - }, - valid: true, - }, - { - desc: "different admin from creator", - genState: &types.GenesisState{ - FactoryDenoms: []types.GenesisDenom{ - { - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/bitcoin", - AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "sei1hjfwcza3e3uzeznf3qthhakdr9juetl7g6esl4", - }, - }, - }, - }, - valid: true, - }, - { - desc: "empty admin", - genState: &types.GenesisState{ - FactoryDenoms: []types.GenesisDenom{ - { - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/bitcoin", - AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "", - }, - }, - }, - }, - valid: true, - }, - { - desc: "no admin", - genState: &types.GenesisState{ - FactoryDenoms: []types.GenesisDenom{ - { - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/bitcoin", - }, - }, - }, - valid: true, - }, - { - desc: "invalid admin", - genState: &types.GenesisState{ - FactoryDenoms: []types.GenesisDenom{ - { - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/bitcoin", - AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "moose", - }, - }, - }, - }, - valid: false, - }, - { - desc: "multiple denoms", - genState: &types.GenesisState{ - FactoryDenoms: []types.GenesisDenom{ - { - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/bitcoin", - AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "", - }, - }, - { - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/litecoin", - AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "", - }, - }, - }, - }, - valid: true, - }, - { - desc: "duplicate denoms", - genState: &types.GenesisState{ - FactoryDenoms: []types.GenesisDenom{ - { - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/bitcoin", - AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "", - }, - }, - { - Denom: "factory/sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw/bitcoin", - AuthorityMetadata: types.DenomAuthorityMetadata{ - Admin: "", - }, - }, - }, - }, - valid: false, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - err := tc.genState.Validate() - if tc.valid { - require.NoError(t, err) - } else { - require.Error(t, err) - } - }) - } -} diff --git a/x/tokenfactory/types/keys.go b/x/tokenfactory/types/keys.go deleted file mode 100644 index 269cc875c2..0000000000 --- a/x/tokenfactory/types/keys.go +++ /dev/null @@ -1,51 +0,0 @@ -package types - -import ( - "strings" -) - -const ( - // ModuleName defines the module name - ModuleName = "tokenfactory" - - // StoreKey defines the primary module store key - StoreKey = ModuleName - - // RouterKey is the message route for slashing - RouterKey = ModuleName - - // QuerierRoute defines the module's query routing key - QuerierRoute = ModuleName - - // MemStoreKey defines the in-memory store key - MemStoreKey = "mem_tokenfactory" -) - -// KeySeparator is used to combine parts of the keys in the store -const KeySeparator = "|" - -var ( - DenomAuthorityMetadataKey = "authoritymetadata" - DenomsPrefixKey = "denoms" - CreatorPrefixKey = "creator" - AdminPrefixKey = "admin" - CreateDenomFeeWhitelistKey = "createdenomfeewhitelist" - DenomAllowListMaxSizeKey = []byte("allowlistmaxsize") -) - -// GetDenomPrefixStore returns the store prefix where all the data associated with a specific denom -// is stored -func GetDenomPrefixStore(denom string) []byte { - return []byte(strings.Join([]string{DenomsPrefixKey, denom, ""}, KeySeparator)) -} - -// GetCreatorsPrefix returns the store prefix where the list of the denoms created by a specific -// creator are stored -func GetCreatorPrefix(creator string) []byte { - return []byte(strings.Join([]string{CreatorPrefixKey, creator, ""}, KeySeparator)) -} - -// GetCreatorsPrefix returns the store prefix where a list of all creator addresses are stored -func GetCreatorsPrefix() []byte { - return []byte(strings.Join([]string{CreatorPrefixKey, ""}, KeySeparator)) -} diff --git a/x/tokenfactory/types/msgs.go b/x/tokenfactory/types/msgs.go deleted file mode 100644 index 0ef112da5c..0000000000 --- a/x/tokenfactory/types/msgs.go +++ /dev/null @@ -1,237 +0,0 @@ -package types - -import ( - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - sdkerrors "github.com/sei-protocol/sei-chain/sei-cosmos/types/errors" - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" -) - -// constants -const ( - TypeMsgCreateDenom = "create_denom" - TypeMsgUpdateDenom = "update_denom" - TypeMsgMint = "mint" - TypeMsgBurn = "burn" - TypeMsgChangeAdmin = "change_admin" - TypeMsgSetDenomMetadata = "set_denom_metadata" -) - -var _ sdk.Msg = &MsgCreateDenom{} - -// NewMsgCreateDenom creates a msg to create a new denom -func NewMsgCreateDenom(sender, subdenom string) *MsgCreateDenom { - return &MsgCreateDenom{ - Sender: sender, - Subdenom: subdenom, - } -} - -func (m MsgCreateDenom) Route() string { return RouterKey } -func (m MsgCreateDenom) Type() string { return TypeMsgCreateDenom } -func (m MsgCreateDenom) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(m.Sender) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) - } - - _, err = GetTokenDenom(m.Sender, m.Subdenom) - if err != nil { - return sdkerrors.Wrap(ErrInvalidDenom, err.Error()) - } - - return nil -} - -func (m MsgCreateDenom) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) -} - -func (m MsgCreateDenom) GetSigners() []sdk.AccAddress { - sender, _ := sdk.AccAddressFromBech32(m.Sender) - return []sdk.AccAddress{sender} -} - -var _ sdk.Msg = &MsgUpdateDenom{} - -// NewMsgUpdateDenom creates a msg to update denom -func NewMsgUpdateDenom(sender, denom string, allowList *banktypes.AllowList) *MsgUpdateDenom { - return &MsgUpdateDenom{ - Sender: sender, - Denom: denom, - AllowList: allowList, - } -} - -func (m MsgUpdateDenom) Route() string { return RouterKey } -func (m MsgUpdateDenom) Type() string { return TypeMsgUpdateDenom } -func (m MsgUpdateDenom) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(m.Sender) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) - } - - _, _, err = DeconstructDenom(m.Denom) - if err != nil { - return sdkerrors.Wrap(ErrInvalidDenom, err.Error()) - } - - return nil -} - -func (m MsgUpdateDenom) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) -} - -func (m MsgUpdateDenom) GetSigners() []sdk.AccAddress { - sender, _ := sdk.AccAddressFromBech32(m.Sender) - return []sdk.AccAddress{sender} -} - -var _ sdk.Msg = &MsgMint{} - -// NewMsgMint creates a message to mint tokens -func NewMsgMint(sender string, amount sdk.Coin) *MsgMint { - return &MsgMint{ - Sender: sender, - Amount: amount, - } -} - -func (m MsgMint) Route() string { return RouterKey } -func (m MsgMint) Type() string { return TypeMsgMint } -func (m MsgMint) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(m.Sender) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) - } - - if !m.Amount.IsValid() || m.Amount.Amount.Equal(sdk.ZeroInt()) { - return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) - } - - return nil -} - -func (m MsgMint) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) -} - -func (m MsgMint) GetSigners() []sdk.AccAddress { - sender, _ := sdk.AccAddressFromBech32(m.Sender) - return []sdk.AccAddress{sender} -} - -var _ sdk.Msg = &MsgBurn{} - -// NewMsgBurn creates a message to burn tokens -func NewMsgBurn(sender string, amount sdk.Coin) *MsgBurn { - return &MsgBurn{ - Sender: sender, - Amount: amount, - } -} - -func (m MsgBurn) Route() string { return RouterKey } -func (m MsgBurn) Type() string { return TypeMsgBurn } -func (m MsgBurn) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(m.Sender) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) - } - - if !m.Amount.IsValid() || m.Amount.Amount.Equal(sdk.ZeroInt()) { - return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, m.Amount.String()) - } - - return nil -} - -func (m MsgBurn) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) -} - -func (m MsgBurn) GetSigners() []sdk.AccAddress { - sender, _ := sdk.AccAddressFromBech32(m.Sender) - return []sdk.AccAddress{sender} -} - -var _ sdk.Msg = &MsgChangeAdmin{} - -// NewMsgChangeAdmin creates a message to change admin for a denom -func NewMsgChangeAdmin(sender, denom, newAdmin string) *MsgChangeAdmin { - return &MsgChangeAdmin{ - Sender: sender, - Denom: denom, - NewAdmin: newAdmin, - } -} - -func (m MsgChangeAdmin) Route() string { return RouterKey } -func (m MsgChangeAdmin) Type() string { return TypeMsgChangeAdmin } -func (m MsgChangeAdmin) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(m.Sender) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) - } - - _, err = sdk.AccAddressFromBech32(m.NewAdmin) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid address (%s)", err) - } - - _, _, err = DeconstructDenom(m.Denom) - if err != nil { - return err - } - - return nil -} - -func (m MsgChangeAdmin) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) -} - -func (m MsgChangeAdmin) GetSigners() []sdk.AccAddress { - sender, _ := sdk.AccAddressFromBech32(m.Sender) - return []sdk.AccAddress{sender} -} - -var _ sdk.Msg = &MsgSetDenomMetadata{} - -// NewMsgChangeAdmin creates a message to burn tokens -func NewMsgSetDenomMetadata(sender string, metadata banktypes.Metadata) *MsgSetDenomMetadata { - return &MsgSetDenomMetadata{ - Sender: sender, - Metadata: metadata, - } -} - -func (m MsgSetDenomMetadata) Route() string { return RouterKey } -func (m MsgSetDenomMetadata) Type() string { return TypeMsgSetDenomMetadata } -func (m MsgSetDenomMetadata) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(m.Sender) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) - } - - err = m.Metadata.Validate() - if err != nil { - return err - } - - _, _, err = DeconstructDenom(m.Metadata.Base) - if err != nil { - return err - } - - return nil -} - -func (m MsgSetDenomMetadata) GetSignBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) -} - -func (m MsgSetDenomMetadata) GetSigners() []sdk.AccAddress { - sender, _ := sdk.AccAddressFromBech32(m.Sender) - return []sdk.AccAddress{sender} -} diff --git a/x/tokenfactory/types/msgs_test.go b/x/tokenfactory/types/msgs_test.go deleted file mode 100644 index 123372e3a3..0000000000 --- a/x/tokenfactory/types/msgs_test.go +++ /dev/null @@ -1,362 +0,0 @@ -package types_test - -import ( - "fmt" - "testing" - - banktypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - - sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types" - "github.com/stretchr/testify/require" - - "github.com/sei-protocol/sei-chain/x/tokenfactory/types" - - "github.com/sei-protocol/sei-chain/sei-tendermint/crypto/ed25519" -) - -// TestMsgCreateDenom tests if valid/invalid create denom messages are properly validated/invalidated -func TestMsgCreateDenom(t *testing.T) { - // generate a private/public key pair and get the respective address - pk1 := ed25519.GenerateSecretKey().Public() - addr1 := sdk.AccAddress(pk1.Address()) - - // make a proper createDenom message - createMsg := func(after func(msg types.MsgCreateDenom) types.MsgCreateDenom) types.MsgCreateDenom { - properMsg := *types.NewMsgCreateDenom( - addr1.String(), - "bitcoin", - ) - - return after(properMsg) - } - - // validate createDenom message was created as intended - msg := createMsg(func(msg types.MsgCreateDenom) types.MsgCreateDenom { - return msg - }) - require.Equal(t, msg.Route(), types.RouterKey) - require.Equal(t, msg.Type(), "create_denom") - signers := msg.GetSigners() - require.Equal(t, len(signers), 1) - require.Equal(t, signers[0].String(), addr1.String()) - - tests := []struct { - name string - msg types.MsgCreateDenom - expectPass bool - }{ - { - name: "proper msg", - msg: createMsg(func(msg types.MsgCreateDenom) types.MsgCreateDenom { - return msg - }), - expectPass: true, - }, - { - name: "empty sender", - msg: createMsg(func(msg types.MsgCreateDenom) types.MsgCreateDenom { - msg.Sender = "" - return msg - }), - expectPass: false, - }, - { - name: "invalid subdenom", - msg: createMsg(func(msg types.MsgCreateDenom) types.MsgCreateDenom { - msg.Subdenom = "thissubdenomismuchtoolongasdkfjaasdfdsafsdlkfnmlksadmflksmdlfmlsakmfdsafasdfasdf" - return msg - }), - expectPass: false, - }, - } - - for _, test := range tests { - if test.expectPass { - require.NoError(t, test.msg.ValidateBasic(), "test: %v", test.name) - } else { - require.Error(t, test.msg.ValidateBasic(), "test: %v", test.name) - } - } -} - -func TestMsgUpdateDenom(t *testing.T) { - // generate a private/public key pair and get the respective address - pk1 := ed25519.GenerateSecretKey().Public() - addr1 := sdk.AccAddress(pk1.Address()) - - // make a proper createDenom message - updateMsg := func(after func(msg types.MsgUpdateDenom) types.MsgUpdateDenom) types.MsgUpdateDenom { - properMsg := *types.NewMsgUpdateDenom( - addr1.String(), - fmt.Sprintf("factory/%s/bitcoin", addr1.String()), - &banktypes.AllowList{Addresses: []string{addr1.String()}}, - ) - - return after(properMsg) - } - - // validate updateDenom message was created as intended - msg := updateMsg(func(msg types.MsgUpdateDenom) types.MsgUpdateDenom { - return msg - }) - require.Equal(t, msg.Route(), types.RouterKey) - require.Equal(t, "update_denom", msg.Type()) - signers := msg.GetSigners() - require.Equal(t, len(signers), 1) - require.Equal(t, signers[0].String(), addr1.String()) - - tests := []struct { - name string - msg types.MsgUpdateDenom - expectPass bool - }{ - { - name: "proper msg", - msg: updateMsg(func(msg types.MsgUpdateDenom) types.MsgUpdateDenom { - return msg - }), - expectPass: true, - }, - { - name: "empty sender", - msg: updateMsg(func(msg types.MsgUpdateDenom) types.MsgUpdateDenom { - msg.Sender = "" - return msg - }), - expectPass: false, - }, - { - name: "invalid subdenom", - msg: updateMsg(func(msg types.MsgUpdateDenom) types.MsgUpdateDenom { - msg.Denom = "thissubdenomismuchtoolongasdkfjaasdfdsafsdlkfnmlksadmflksmdlfmlsakmfdsafasdfasdf" - return msg - }), - expectPass: false, - }, - } - - for _, test := range tests { - if test.expectPass { - require.NoError(t, test.msg.ValidateBasic(), "test: %v", test.name) - } else { - require.Error(t, test.msg.ValidateBasic(), "test: %v", test.name) - } - } -} - -// TestMsgMint tests if valid/invalid create denom messages are properly validated/invalidated -func TestMsgMint(t *testing.T) { - // generate a private/public key pair and get the respective address - pk1 := ed25519.GenerateSecretKey().Public() - addr1 := sdk.AccAddress(pk1.Address()) - - // make a proper mint message - createMsg := func(after func(msg types.MsgMint) types.MsgMint) types.MsgMint { - properMsg := *types.NewMsgMint( - addr1.String(), - sdk.NewCoin("bitcoin", sdk.NewInt(500000000)), - ) - - return after(properMsg) - } - - // validate mint message was created as intended - msg := createMsg(func(msg types.MsgMint) types.MsgMint { - return msg - }) - require.Equal(t, msg.Route(), types.RouterKey) - require.Equal(t, msg.Type(), "mint") - signers := msg.GetSigners() - require.Equal(t, len(signers), 1) - require.Equal(t, signers[0].String(), addr1.String()) - - tests := []struct { - name string - msg types.MsgMint - expectPass bool - }{ - { - name: "proper msg", - msg: createMsg(func(msg types.MsgMint) types.MsgMint { - return msg - }), - expectPass: true, - }, - { - name: "empty sender", - msg: createMsg(func(msg types.MsgMint) types.MsgMint { - msg.Sender = "" - return msg - }), - expectPass: false, - }, - { - name: "zero amount", - msg: createMsg(func(msg types.MsgMint) types.MsgMint { - msg.Amount = sdk.NewCoin("bitcoin", sdk.ZeroInt()) - return msg - }), - expectPass: false, - }, - { - name: "negative amount", - msg: createMsg(func(msg types.MsgMint) types.MsgMint { - msg.Amount.Amount = sdk.NewInt(-10000000) - return msg - }), - expectPass: false, - }, - } - - for _, test := range tests { - if test.expectPass { - require.NoError(t, test.msg.ValidateBasic(), "test: %v", test.name) - } else { - require.Error(t, test.msg.ValidateBasic(), "test: %v", test.name) - } - } -} - -// TestMsgBurn tests if valid/invalid create denom messages are properly validated/invalidated -func TestMsgBurn(t *testing.T) { - // generate a private/public key pair and get the respective address - pk1 := ed25519.GenerateSecretKey().Public() - addr1 := sdk.AccAddress(pk1.Address()) - - // make a proper burn message - baseMsg := types.NewMsgBurn( - addr1.String(), - sdk.NewCoin("bitcoin", sdk.NewInt(500000000)), - ) - - // validate burn message was created as intended - require.Equal(t, baseMsg.Route(), types.RouterKey) - require.Equal(t, baseMsg.Type(), "burn") - signers := baseMsg.GetSigners() - require.Equal(t, len(signers), 1) - require.Equal(t, signers[0].String(), addr1.String()) - - tests := []struct { - name string - msg func() *types.MsgBurn - expectPass bool - }{ - { - name: "proper msg", - msg: func() *types.MsgBurn { - msg := baseMsg - return msg - }, - expectPass: true, - }, - { - name: "empty sender", - msg: func() *types.MsgBurn { - msg := baseMsg - msg.Sender = "" - return msg - }, - expectPass: false, - }, - { - name: "zero amount", - msg: func() *types.MsgBurn { - msg := baseMsg - msg.Amount.Amount = sdk.ZeroInt() - return msg - }, - expectPass: false, - }, - { - name: "negative amount", - msg: func() *types.MsgBurn { - msg := baseMsg - msg.Amount.Amount = sdk.NewInt(-10000000) - return msg - }, - expectPass: false, - }, - } - - for _, test := range tests { - if test.expectPass { - require.NoError(t, test.msg().ValidateBasic(), "test: %v", test.name) - } else { - require.Error(t, test.msg().ValidateBasic(), "test: %v", test.name) - } - } -} - -// TestMsgChangeAdmin tests if valid/invalid create denom messages are properly validated/invalidated -func TestMsgChangeAdmin(t *testing.T) { - // generate a private/public key pair and get the respective address - pk1 := ed25519.GenerateSecretKey().Public() - addr1 := sdk.AccAddress(pk1.Address()) - pk2 := ed25519.GenerateSecretKey().Public() - addr2 := sdk.AccAddress(pk2.Address()) - tokenFactoryDenom := fmt.Sprintf("factory/%s/bitcoin", addr1.String()) - - // make a proper changeAdmin message - baseMsg := types.NewMsgChangeAdmin( - addr1.String(), - tokenFactoryDenom, - addr2.String(), - ) - - // validate changeAdmin message was created as intended - require.Equal(t, baseMsg.Route(), types.RouterKey) - require.Equal(t, baseMsg.Type(), "change_admin") - signers := baseMsg.GetSigners() - require.Equal(t, len(signers), 1) - require.Equal(t, signers[0].String(), addr1.String()) - - tests := []struct { - name string - msg func() *types.MsgChangeAdmin - expectPass bool - }{ - { - name: "proper msg", - msg: func() *types.MsgChangeAdmin { - msg := baseMsg - return msg - }, - expectPass: true, - }, - { - name: "empty sender", - msg: func() *types.MsgChangeAdmin { - msg := baseMsg - msg.Sender = "" - return msg - }, - expectPass: false, - }, - { - name: "empty newAdmin", - msg: func() *types.MsgChangeAdmin { - msg := baseMsg - msg.NewAdmin = "" - return msg - }, - expectPass: false, - }, - { - name: "invalid denom", - msg: func() *types.MsgChangeAdmin { - msg := baseMsg - msg.Denom = "bitcoin" - return msg - }, - expectPass: false, - }, - } - - for _, test := range tests { - if test.expectPass { - require.NoError(t, test.msg().ValidateBasic(), "test: %v", test.name) - } else { - require.Error(t, test.msg().ValidateBasic(), "test: %v", test.name) - } - } -} diff --git a/x/tokenfactory/types/params.go b/x/tokenfactory/types/params.go deleted file mode 100644 index db0a89992e..0000000000 --- a/x/tokenfactory/types/params.go +++ /dev/null @@ -1,46 +0,0 @@ -package types - -import ( - "fmt" - - paramtypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/params/types" -) - -// DefaultDenomAllowListMaxSize default denom allowlist max size and can be overridden by governance proposal. -const DefaultDenomAllowListMaxSize = 2000 - -// ParamKeyTable ParamTable for tokenfactory module. -func ParamKeyTable() paramtypes.KeyTable { - return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) -} - -// DefaultParams default tokenfactory module parameters. -func DefaultParams() Params { - return Params{ - DenomAllowlistMaxSize: DefaultDenomAllowListMaxSize, - } -} - -// Validate validate params. -func (p Params) Validate() error { - if err := validateDenomAllowListMaxSize(p.DenomAllowlistMaxSize); err != nil { - return err - } - return nil -} - -// ParamSetPairs Implements params.ParamSet. -func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { - return paramtypes.ParamSetPairs{ - paramtypes.NewParamSetPair(DenomAllowListMaxSizeKey, &p.DenomAllowlistMaxSize, validateDenomAllowListMaxSize), - } -} - -// validateDenomAllowListMaxSize validates a parameter value is within a valid range. -func validateDenomAllowListMaxSize(i interface{}) error { - _, ok := i.(uint32) - if !ok { - return fmt.Errorf("invalid parameter type: %T", i) - } - return nil -} diff --git a/x/tokenfactory/types/params.pb.go b/x/tokenfactory/types/params.pb.go deleted file mode 100644 index 43a94ea462..0000000000 --- a/x/tokenfactory/types/params.pb.go +++ /dev/null @@ -1,301 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: tokenfactory/params.proto - -package types - -import ( - fmt "fmt" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// 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 { - DenomAllowlistMaxSize uint32 `protobuf:"varint,1,opt,name=denom_allowlist_max_size,json=denomAllowlistMaxSize,proto3" json:"denom_allowlist_max_size,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_0f39a375875b281a, []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) GetDenomAllowlistMaxSize() uint32 { - if m != nil { - return m.DenomAllowlistMaxSize - } - return 0 -} - -func init() { - proto.RegisterType((*Params)(nil), "seiprotocol.seichain.tokenfactory.Params") -} - -func init() { proto.RegisterFile("tokenfactory/params.proto", fileDescriptor_0f39a375875b281a) } - -var fileDescriptor_0f39a375875b281a = []byte{ - // 191 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2c, 0xc9, 0xcf, 0x4e, - 0xcd, 0x4b, 0x4b, 0x4c, 0x2e, 0xc9, 0x2f, 0xaa, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, - 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x52, 0x2c, 0x4e, 0xcd, 0x04, 0xb3, 0x92, 0xf3, 0x73, 0xf4, - 0x8a, 0x53, 0x33, 0x93, 0x33, 0x12, 0x33, 0xf3, 0xf4, 0x90, 0xd5, 0x2b, 0x39, 0x72, 0xb1, 0x05, - 0x80, 0xb5, 0x08, 0x99, 0x73, 0x49, 0xa4, 0xa4, 0xe6, 0xe5, 0xe7, 0xc6, 0x27, 0xe6, 0xe4, 0xe4, - 0x97, 0xe7, 0x64, 0x16, 0x97, 0xc4, 0xe7, 0x26, 0x56, 0xc4, 0x17, 0x67, 0x56, 0xa5, 0x4a, 0x30, - 0x2a, 0x30, 0x6a, 0xf0, 0x06, 0x89, 0x82, 0xe5, 0x1d, 0x61, 0xd2, 0xbe, 0x89, 0x15, 0xc1, 0x99, - 0x55, 0xa9, 0x4e, 0x01, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, - 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0x65, 0x96, - 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x5f, 0x9c, 0x9a, 0xa9, 0x0b, 0x73, - 0x0b, 0x98, 0x03, 0x76, 0x8c, 0x7e, 0x85, 0x3e, 0x8a, 0xf3, 0x4b, 0x2a, 0x0b, 0x52, 0x8b, 0x93, - 0xd8, 0xc0, 0x0a, 0x8d, 0x01, 0x03, 0x00, 0xbf, 0x4a, 0x3c, 0xf9, 0xdb, 0x00, 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 m.DenomAllowlistMaxSize != 0 { - i = encodeVarintParams(dAtA, i, uint64(m.DenomAllowlistMaxSize)) - i-- - dAtA[i] = 0x8 - } - 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 m.DenomAllowlistMaxSize != 0 { - n += 1 + sovParams(uint64(m.DenomAllowlistMaxSize)) - } - 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 != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DenomAllowlistMaxSize", wireType) - } - m.DenomAllowlistMaxSize = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowParams - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.DenomAllowlistMaxSize |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - 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") -) diff --git a/x/tokenfactory/types/params_test.go b/x/tokenfactory/types/params_test.go deleted file mode 100644 index af2ac6630d..0000000000 --- a/x/tokenfactory/types/params_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package types - -import ( - "bytes" - "reflect" - "testing" - - "github.com/sei-protocol/sei-chain/sei-cosmos/x/params/types" -) - -func TestDefaultParams(t *testing.T) { - tests := []struct { - name string - want Params - }{ - { - name: "default params", - want: Params{ - DenomAllowlistMaxSize: 2000, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := DefaultParams(); !reflect.DeepEqual(got, tt.want) { - t.Errorf("DefaultParams() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestParams_Validate(t *testing.T) { - type fields struct { - DenomAllowlistMaxSize uint32 - } - tests := []struct { - name string - fields fields - wantErr bool - errMsg string - }{ - { - name: "valid params", - fields: fields{ - DenomAllowlistMaxSize: 2000, - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := Params{ - DenomAllowlistMaxSize: tt.fields.DenomAllowlistMaxSize, - } - err := p.Validate() - if (err != nil) != tt.wantErr { - t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) - } - if err != nil && err.Error() != tt.errMsg { - t.Errorf("Validate() error message = %v, want %v", err.Error(), tt.errMsg) - } - }) - } -} - -func Test_validateDenomAllowListMaxSize(t *testing.T) { - type args struct { - i interface{} - } - tests := []struct { - name string - args args - wantErr bool - errMsg string - }{ - { - name: "valid denom allowlist max size", - args: args{ - i: uint32(2000), - }, - wantErr: false, - }, - { - name: "invalid denom allowlist max size", - args: args{ - i: int32(-1), - }, - wantErr: true, - errMsg: "invalid parameter type: int32", - }, - { - name: "invalid denom allowlist large int value", - args: args{ - i: 20000000000000, - }, - wantErr: true, - errMsg: "invalid parameter type: int", - }, - { - name: "invalid denom allowlist max size type", - args: args{ - i: "2000", - }, - wantErr: true, - errMsg: "invalid parameter type: string", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := validateDenomAllowListMaxSize(tt.args.i) - if (err != nil) != tt.wantErr { - t.Errorf("validateDenomAllowListMaxSize() error = %v, wantErr %v", err, tt.wantErr) - } - if err != nil && err.Error() != tt.errMsg { - t.Errorf("validateDenomAllowListMaxSize() error message = %v, want %v", err.Error(), tt.errMsg) - } - }) - } -} - -func TestParams_ParamSetPairs(t *testing.T) { - type fields struct { - DenomAllowlistMaxSize uint32 - } - allowListSize := uint32(20) - params := &Params{DenomAllowlistMaxSize: allowListSize} - tests := []struct { - name string - fields fields - want types.ParamSetPairs - }{ - { - name: "valid param set pairs", - fields: fields{ - DenomAllowlistMaxSize: allowListSize, - }, - want: types.ParamSetPairs{ - types.NewParamSetPair([]byte("allowlistmaxsize"), - ¶ms.DenomAllowlistMaxSize, - validateDenomAllowListMaxSize), - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := params - got := p.ParamSetPairs() - if len(got) != len(tt.want) || !bytes.Equal(got[0].Key, tt.want[0].Key) || - got[0].Value != tt.want[0].Value || - reflect.ValueOf(got[0].ValidatorFn).Pointer() != reflect.ValueOf(tt.want[0].ValidatorFn).Pointer() { - t.Errorf("ParamSetPairs() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/x/tokenfactory/types/query.pb.go b/x/tokenfactory/types/query.pb.go deleted file mode 100644 index d69b203801..0000000000 --- a/x/tokenfactory/types/query.pb.go +++ /dev/null @@ -1,2236 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: tokenfactory/query.proto - -package types - -import ( - context "context" - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" - query "github.com/sei-protocol/sei-chain/sei-cosmos/types/query" - types "github.com/sei-protocol/sei-chain/sei-cosmos/x/bank/types" - _ "google.golang.org/genproto/googleapis/api/annotations" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - io "io" - math "math" - math_bits "math/bits" -) - -// 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 - -// QueryParamsRequest is the request type for the Query/Params RPC method. -type QueryParamsRequest struct { -} - -func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } -func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } -func (*QueryParamsRequest) ProtoMessage() {} -func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_78516c77a1ba9513, []int{0} -} -func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryParamsRequest.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 *QueryParamsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryParamsRequest.Merge(m, src) -} -func (m *QueryParamsRequest) XXX_Size() int { - return m.Size() -} -func (m *QueryParamsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo - -// QueryParamsResponse is the response type for the Query/Params RPC method. -type QueryParamsResponse struct { - // params defines the parameters of the module. - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` -} - -func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } -func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } -func (*QueryParamsResponse) ProtoMessage() {} -func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_78516c77a1ba9513, []int{1} -} -func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryParamsResponse.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 *QueryParamsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryParamsResponse.Merge(m, src) -} -func (m *QueryParamsResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryParamsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo - -func (m *QueryParamsResponse) GetParams() Params { - if m != nil { - return m.Params - } - return Params{} -} - -// QueryDenomAuthorityMetadataRequest defines the request structure for the -// DenomAuthorityMetadata gRPC query. -type QueryDenomAuthorityMetadataRequest struct { - Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty" yaml:"denom"` -} - -func (m *QueryDenomAuthorityMetadataRequest) Reset() { *m = QueryDenomAuthorityMetadataRequest{} } -func (m *QueryDenomAuthorityMetadataRequest) String() string { return proto.CompactTextString(m) } -func (*QueryDenomAuthorityMetadataRequest) ProtoMessage() {} -func (*QueryDenomAuthorityMetadataRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_78516c77a1ba9513, []int{2} -} -func (m *QueryDenomAuthorityMetadataRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryDenomAuthorityMetadataRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryDenomAuthorityMetadataRequest.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 *QueryDenomAuthorityMetadataRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryDenomAuthorityMetadataRequest.Merge(m, src) -} -func (m *QueryDenomAuthorityMetadataRequest) XXX_Size() int { - return m.Size() -} -func (m *QueryDenomAuthorityMetadataRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryDenomAuthorityMetadataRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryDenomAuthorityMetadataRequest proto.InternalMessageInfo - -func (m *QueryDenomAuthorityMetadataRequest) GetDenom() string { - if m != nil { - return m.Denom - } - return "" -} - -// QueryDenomAuthorityMetadataResponse defines the response structure for the -// DenomAuthorityMetadata gRPC query. -type QueryDenomAuthorityMetadataResponse struct { - AuthorityMetadata DenomAuthorityMetadata `protobuf:"bytes,1,opt,name=authority_metadata,json=authorityMetadata,proto3" json:"authority_metadata" yaml:"authority_metadata"` -} - -func (m *QueryDenomAuthorityMetadataResponse) Reset() { *m = QueryDenomAuthorityMetadataResponse{} } -func (m *QueryDenomAuthorityMetadataResponse) String() string { return proto.CompactTextString(m) } -func (*QueryDenomAuthorityMetadataResponse) ProtoMessage() {} -func (*QueryDenomAuthorityMetadataResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_78516c77a1ba9513, []int{3} -} -func (m *QueryDenomAuthorityMetadataResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryDenomAuthorityMetadataResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryDenomAuthorityMetadataResponse.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 *QueryDenomAuthorityMetadataResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryDenomAuthorityMetadataResponse.Merge(m, src) -} -func (m *QueryDenomAuthorityMetadataResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryDenomAuthorityMetadataResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryDenomAuthorityMetadataResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryDenomAuthorityMetadataResponse proto.InternalMessageInfo - -func (m *QueryDenomAuthorityMetadataResponse) GetAuthorityMetadata() DenomAuthorityMetadata { - if m != nil { - return m.AuthorityMetadata - } - return DenomAuthorityMetadata{} -} - -// QueryDenomsFromCreatorRequest defines the request structure for the -// DenomsFromCreator gRPC query. -type QueryDenomsFromCreatorRequest struct { - Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` - Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` -} - -func (m *QueryDenomsFromCreatorRequest) Reset() { *m = QueryDenomsFromCreatorRequest{} } -func (m *QueryDenomsFromCreatorRequest) String() string { return proto.CompactTextString(m) } -func (*QueryDenomsFromCreatorRequest) ProtoMessage() {} -func (*QueryDenomsFromCreatorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_78516c77a1ba9513, []int{4} -} -func (m *QueryDenomsFromCreatorRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryDenomsFromCreatorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryDenomsFromCreatorRequest.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 *QueryDenomsFromCreatorRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryDenomsFromCreatorRequest.Merge(m, src) -} -func (m *QueryDenomsFromCreatorRequest) XXX_Size() int { - return m.Size() -} -func (m *QueryDenomsFromCreatorRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryDenomsFromCreatorRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryDenomsFromCreatorRequest proto.InternalMessageInfo - -func (m *QueryDenomsFromCreatorRequest) GetCreator() string { - if m != nil { - return m.Creator - } - return "" -} - -func (m *QueryDenomsFromCreatorRequest) GetPagination() *query.PageRequest { - if m != nil { - return m.Pagination - } - return nil -} - -// QueryDenomsFromCreatorResponse defines the response structure for the -// DenomsFromCreator gRPC query. -type QueryDenomsFromCreatorResponse struct { - Denoms []string `protobuf:"bytes,1,rep,name=denoms,proto3" json:"denoms,omitempty" yaml:"denoms"` - Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` -} - -func (m *QueryDenomsFromCreatorResponse) Reset() { *m = QueryDenomsFromCreatorResponse{} } -func (m *QueryDenomsFromCreatorResponse) String() string { return proto.CompactTextString(m) } -func (*QueryDenomsFromCreatorResponse) ProtoMessage() {} -func (*QueryDenomsFromCreatorResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_78516c77a1ba9513, []int{5} -} -func (m *QueryDenomsFromCreatorResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryDenomsFromCreatorResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryDenomsFromCreatorResponse.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 *QueryDenomsFromCreatorResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryDenomsFromCreatorResponse.Merge(m, src) -} -func (m *QueryDenomsFromCreatorResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryDenomsFromCreatorResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryDenomsFromCreatorResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryDenomsFromCreatorResponse proto.InternalMessageInfo - -func (m *QueryDenomsFromCreatorResponse) GetDenoms() []string { - if m != nil { - return m.Denoms - } - return nil -} - -func (m *QueryDenomsFromCreatorResponse) GetPagination() *query.PageResponse { - if m != nil { - return m.Pagination - } - return nil -} - -// QueryDenomMetadataRequest is the request type for the DenomMetadata gRPC method. -type QueryDenomMetadataRequest struct { - // denom is the coin denom to query the metadata for. - Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"` -} - -func (m *QueryDenomMetadataRequest) Reset() { *m = QueryDenomMetadataRequest{} } -func (m *QueryDenomMetadataRequest) String() string { return proto.CompactTextString(m) } -func (*QueryDenomMetadataRequest) ProtoMessage() {} -func (*QueryDenomMetadataRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_78516c77a1ba9513, []int{6} -} -func (m *QueryDenomMetadataRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryDenomMetadataRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryDenomMetadataRequest.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 *QueryDenomMetadataRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryDenomMetadataRequest.Merge(m, src) -} -func (m *QueryDenomMetadataRequest) XXX_Size() int { - return m.Size() -} -func (m *QueryDenomMetadataRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryDenomMetadataRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryDenomMetadataRequest proto.InternalMessageInfo - -func (m *QueryDenomMetadataRequest) GetDenom() string { - if m != nil { - return m.Denom - } - return "" -} - -// QueryDenomMetadataResponse is the response type for the Query/DenomMetadata gRPC -// method. -type QueryDenomMetadataResponse struct { - // metadata describes and provides all the client information for the requested token. - Metadata types.Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata"` -} - -func (m *QueryDenomMetadataResponse) Reset() { *m = QueryDenomMetadataResponse{} } -func (m *QueryDenomMetadataResponse) String() string { return proto.CompactTextString(m) } -func (*QueryDenomMetadataResponse) ProtoMessage() {} -func (*QueryDenomMetadataResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_78516c77a1ba9513, []int{7} -} -func (m *QueryDenomMetadataResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryDenomMetadataResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryDenomMetadataResponse.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 *QueryDenomMetadataResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryDenomMetadataResponse.Merge(m, src) -} -func (m *QueryDenomMetadataResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryDenomMetadataResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryDenomMetadataResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryDenomMetadataResponse proto.InternalMessageInfo - -func (m *QueryDenomMetadataResponse) GetMetadata() types.Metadata { - if m != nil { - return m.Metadata - } - return types.Metadata{} -} - -// QueryDenomAllowListRequest is the request type for the DenomAllowList gRPC method -type QueryDenomAllowListRequest struct { - // denom is the coin denom to query the allowlist for. - Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"` -} - -func (m *QueryDenomAllowListRequest) Reset() { *m = QueryDenomAllowListRequest{} } -func (m *QueryDenomAllowListRequest) String() string { return proto.CompactTextString(m) } -func (*QueryDenomAllowListRequest) ProtoMessage() {} -func (*QueryDenomAllowListRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_78516c77a1ba9513, []int{8} -} -func (m *QueryDenomAllowListRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryDenomAllowListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryDenomAllowListRequest.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 *QueryDenomAllowListRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryDenomAllowListRequest.Merge(m, src) -} -func (m *QueryDenomAllowListRequest) XXX_Size() int { - return m.Size() -} -func (m *QueryDenomAllowListRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryDenomAllowListRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryDenomAllowListRequest proto.InternalMessageInfo - -func (m *QueryDenomAllowListRequest) GetDenom() string { - if m != nil { - return m.Denom - } - return "" -} - -// QueryDenomAllowListResponse is the response type for the DenomAllowList gRPC -// method. -type QueryDenomAllowListResponse struct { - // allow_list provides addresses allowed for the requested token. - AllowList types.AllowList `protobuf:"bytes,1,opt,name=allow_list,json=allowList,proto3" json:"allow_list"` -} - -func (m *QueryDenomAllowListResponse) Reset() { *m = QueryDenomAllowListResponse{} } -func (m *QueryDenomAllowListResponse) String() string { return proto.CompactTextString(m) } -func (*QueryDenomAllowListResponse) ProtoMessage() {} -func (*QueryDenomAllowListResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_78516c77a1ba9513, []int{9} -} -func (m *QueryDenomAllowListResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryDenomAllowListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryDenomAllowListResponse.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 *QueryDenomAllowListResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryDenomAllowListResponse.Merge(m, src) -} -func (m *QueryDenomAllowListResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryDenomAllowListResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryDenomAllowListResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryDenomAllowListResponse proto.InternalMessageInfo - -func (m *QueryDenomAllowListResponse) GetAllowList() types.AllowList { - if m != nil { - return m.AllowList - } - return types.AllowList{} -} - -func init() { - proto.RegisterType((*QueryParamsRequest)(nil), "seiprotocol.seichain.tokenfactory.QueryParamsRequest") - proto.RegisterType((*QueryParamsResponse)(nil), "seiprotocol.seichain.tokenfactory.QueryParamsResponse") - proto.RegisterType((*QueryDenomAuthorityMetadataRequest)(nil), "seiprotocol.seichain.tokenfactory.QueryDenomAuthorityMetadataRequest") - proto.RegisterType((*QueryDenomAuthorityMetadataResponse)(nil), "seiprotocol.seichain.tokenfactory.QueryDenomAuthorityMetadataResponse") - proto.RegisterType((*QueryDenomsFromCreatorRequest)(nil), "seiprotocol.seichain.tokenfactory.QueryDenomsFromCreatorRequest") - proto.RegisterType((*QueryDenomsFromCreatorResponse)(nil), "seiprotocol.seichain.tokenfactory.QueryDenomsFromCreatorResponse") - proto.RegisterType((*QueryDenomMetadataRequest)(nil), "seiprotocol.seichain.tokenfactory.QueryDenomMetadataRequest") - proto.RegisterType((*QueryDenomMetadataResponse)(nil), "seiprotocol.seichain.tokenfactory.QueryDenomMetadataResponse") - proto.RegisterType((*QueryDenomAllowListRequest)(nil), "seiprotocol.seichain.tokenfactory.QueryDenomAllowListRequest") - proto.RegisterType((*QueryDenomAllowListResponse)(nil), "seiprotocol.seichain.tokenfactory.QueryDenomAllowListResponse") -} - -func init() { proto.RegisterFile("tokenfactory/query.proto", fileDescriptor_78516c77a1ba9513) } - -var fileDescriptor_78516c77a1ba9513 = []byte{ - // 769 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x4f, 0x4f, 0x13, 0x4f, - 0x18, 0xee, 0xf0, 0xfb, 0x51, 0x61, 0x14, 0x22, 0x23, 0x31, 0x50, 0x65, 0x2b, 0x63, 0x44, 0x20, - 0xb0, 0x1b, 0x4a, 0xc0, 0xf8, 0x07, 0xb5, 0x45, 0x20, 0x26, 0x90, 0x60, 0x8f, 0x26, 0xda, 0x4c, - 0xcb, 0x50, 0x36, 0x74, 0x77, 0xca, 0xce, 0x54, 0x6d, 0x08, 0x17, 0xaf, 0x5e, 0x4c, 0xd4, 0x4f, - 0xe1, 0xc9, 0xf8, 0x25, 0xf0, 0x62, 0x48, 0xbc, 0x78, 0x6a, 0x0c, 0xf5, 0x13, 0xf4, 0xe0, 0xd9, - 0x74, 0x66, 0xfa, 0x67, 0xdb, 0x15, 0x5a, 0x38, 0x75, 0xfa, 0xce, 0xfb, 0x3c, 0xf3, 0x3c, 0xb3, - 0xcf, 0xbc, 0x70, 0x44, 0xb0, 0x5d, 0xea, 0x6e, 0x93, 0x8c, 0x60, 0x5e, 0xd1, 0xda, 0x2b, 0x50, - 0xaf, 0x68, 0xe6, 0x3d, 0x26, 0x18, 0x1a, 0xe7, 0xd4, 0x96, 0xab, 0x0c, 0xcb, 0x99, 0x9c, 0xda, - 0x99, 0x1d, 0x62, 0xbb, 0x66, 0x73, 0x7b, 0xc4, 0xc8, 0x30, 0xee, 0x30, 0x6e, 0xa5, 0x89, 0xbb, - 0x6b, 0xbd, 0x9a, 0x4b, 0x53, 0x41, 0xe6, 0xe4, 0x1f, 0x45, 0x11, 0x99, 0xae, 0xef, 0x73, 0xaa, - 0xb8, 0xeb, 0x5d, 0x79, 0x92, 0xb5, 0x5d, 0x22, 0x6c, 0xe6, 0xea, 0xde, 0xe1, 0x2c, 0xcb, 0x32, - 0xb9, 0xb4, 0xaa, 0x2b, 0x5d, 0xbd, 0x9e, 0x65, 0x2c, 0x9b, 0xa3, 0x16, 0xc9, 0xdb, 0x16, 0x71, - 0x5d, 0x26, 0x24, 0x84, 0xeb, 0xdd, 0x5b, 0x3e, 0xf1, 0xa4, 0x20, 0x76, 0x98, 0x67, 0x8b, 0x62, - 0xca, 0xa1, 0x82, 0x6c, 0x11, 0x41, 0x74, 0xdb, 0xa8, 0xaf, 0x2d, 0x4f, 0x3c, 0xe2, 0x68, 0x06, - 0x3c, 0x0c, 0xd1, 0xb3, 0xaa, 0xae, 0x4d, 0x59, 0x4c, 0xd2, 0xbd, 0x02, 0xe5, 0x02, 0xbf, 0x84, - 0x57, 0x7c, 0x55, 0x9e, 0x67, 0x2e, 0xa7, 0x68, 0x0d, 0x86, 0x15, 0x78, 0x04, 0xdc, 0x00, 0x93, - 0x17, 0x63, 0x53, 0xe6, 0xa9, 0x57, 0x64, 0x2a, 0x8a, 0xc4, 0xff, 0x87, 0xa5, 0x68, 0x28, 0xa9, - 0xe1, 0x78, 0x1d, 0x62, 0xc9, 0xff, 0x84, 0xba, 0xcc, 0x89, 0xd7, 0x64, 0x6f, 0x68, 0xd5, 0x5a, - 0x05, 0x9a, 0x80, 0xbd, 0x5b, 0xd5, 0x06, 0x79, 0x5a, 0x7f, 0xe2, 0x72, 0xa5, 0x14, 0xbd, 0x54, - 0x24, 0x4e, 0xee, 0x1e, 0x96, 0x65, 0x9c, 0x54, 0xdb, 0xf8, 0x2b, 0x80, 0x37, 0x4f, 0xa4, 0xd3, - 0xf2, 0xdf, 0x01, 0x88, 0xda, 0xef, 0x48, 0x7b, 0xb9, 0xdb, 0x81, 0x97, 0x60, 0xfe, 0xc4, 0x78, - 0xd5, 0x5b, 0xa5, 0x14, 0x1d, 0x55, 0xe2, 0xda, 0x8f, 0xc0, 0xc9, 0x21, 0xd2, 0x8a, 0xc2, 0x9f, - 0x00, 0x1c, 0x6b, 0xa8, 0xe6, 0xab, 0x1e, 0x73, 0x96, 0x3d, 0x4a, 0x04, 0xf3, 0x6a, 0xfe, 0x67, - 0xe0, 0x85, 0x8c, 0xaa, 0xe8, 0x1b, 0x40, 0x95, 0x52, 0x74, 0x50, 0x1d, 0xa2, 0x37, 0x70, 0xb2, - 0xd6, 0x82, 0x56, 0x21, 0x6c, 0x64, 0x6a, 0xa4, 0x47, 0x9a, 0x9a, 0x30, 0x55, 0x00, 0xcd, 0x6a, - 0x00, 0x4d, 0x15, 0x6e, 0x1d, 0x40, 0x73, 0x93, 0x64, 0xa9, 0x3e, 0x29, 0xd9, 0x84, 0xc4, 0x1f, - 0x01, 0x34, 0xfe, 0xa5, 0x4b, 0x5f, 0xe4, 0x14, 0x0c, 0xcb, 0x9b, 0xaf, 0xe6, 0xe0, 0xbf, 0xc9, - 0xfe, 0xc4, 0x50, 0xa5, 0x14, 0x1d, 0x68, 0xfa, 0x32, 0x1c, 0x27, 0x75, 0x03, 0x5a, 0x0b, 0x50, - 0x75, 0xfb, 0x54, 0x55, 0xea, 0x1c, 0x9f, 0xac, 0x39, 0x38, 0xda, 0x50, 0xd5, 0x9a, 0x94, 0x61, - 0x5f, 0x52, 0x6a, 0xb9, 0x78, 0x01, 0x23, 0x41, 0x10, 0x6d, 0xe2, 0x11, 0xec, 0x6b, 0x89, 0xc0, - 0x58, 0x43, 0x97, 0xbb, 0x5b, 0x57, 0x54, 0xff, 0xcc, 0x2a, 0xc2, 0x75, 0x10, 0x8e, 0x35, 0xd3, - 0xc7, 0x73, 0x39, 0xf6, 0x7a, 0xdd, 0xe6, 0xe2, 0x64, 0x49, 0x69, 0x78, 0x2d, 0x10, 0xa3, 0x35, - 0x2d, 0x43, 0x48, 0xaa, 0xc5, 0x54, 0xce, 0xe6, 0x42, 0xab, 0x32, 0x02, 0x55, 0xd5, 0xb1, 0x5a, - 0x56, 0x3f, 0xa9, 0x15, 0x62, 0x5f, 0xfa, 0x60, 0xaf, 0x3c, 0x04, 0x7d, 0x06, 0x30, 0xac, 0xde, - 0x1f, 0x5a, 0xe8, 0x20, 0xde, 0xed, 0x83, 0x20, 0xb2, 0xd8, 0x2d, 0x4c, 0x19, 0xc1, 0xb1, 0xb7, - 0x3f, 0x7e, 0x7f, 0xe8, 0x99, 0x41, 0xd3, 0x16, 0xa7, 0xf6, 0x6c, 0x8d, 0xc0, 0xaa, 0x11, 0x58, - 0x01, 0x03, 0x09, 0xfd, 0x01, 0xf0, 0x6a, 0xf0, 0x0b, 0x43, 0x2b, 0x9d, 0xca, 0x38, 0x71, 0xa0, - 0x44, 0x56, 0xcf, 0x4b, 0xa3, 0xdd, 0x6d, 0x48, 0x77, 0x6b, 0x68, 0xa5, 0x13, 0x77, 0xea, 0x21, - 0x58, 0xfb, 0xf2, 0xf7, 0x20, 0x60, 0x48, 0xa3, 0x6f, 0x00, 0x0e, 0xf8, 0x32, 0x8a, 0x1e, 0x74, - 0x25, 0xb4, 0xd5, 0xe6, 0xd2, 0x19, 0xd1, 0xda, 0xdd, 0x7d, 0xe9, 0x6e, 0x01, 0xcd, 0x77, 0xe1, - 0xae, 0xee, 0xa5, 0x0c, 0xe0, 0x50, 0xdb, 0xe0, 0x40, 0x8f, 0xbb, 0x52, 0x14, 0x30, 0x0b, 0x23, - 0xf1, 0x73, 0x30, 0x68, 0x5f, 0x4f, 0xa5, 0xaf, 0x65, 0x14, 0xef, 0xdc, 0x57, 0x6a, 0xdb, 0x63, - 0x4e, 0x4a, 0x4f, 0x58, 0x6b, 0x5f, 0x2f, 0x0e, 0xd0, 0x77, 0x00, 0x07, 0xfd, 0x4f, 0x18, 0x75, - 0x77, 0xe9, 0xad, 0xe3, 0x22, 0xf2, 0xf0, 0xac, 0x70, 0x6d, 0x6e, 0x49, 0x9a, 0xbb, 0x83, 0x16, - 0xba, 0xf8, 0x68, 0x8d, 0x51, 0x93, 0xd8, 0x3c, 0x3c, 0x36, 0xc0, 0xd1, 0xb1, 0x01, 0x7e, 0x1d, - 0x1b, 0xe0, 0x7d, 0xd9, 0x08, 0x1d, 0x95, 0x8d, 0xd0, 0xcf, 0xb2, 0x11, 0x7a, 0xbe, 0x98, 0xb5, - 0xc5, 0x4e, 0x21, 0x6d, 0x66, 0x98, 0xd3, 0x46, 0x3d, 0xab, 0xb8, 0xdf, 0xf8, 0xd9, 0x45, 0x31, - 0x4f, 0x79, 0x3a, 0x2c, 0x1b, 0xe7, 0xff, 0x0e, 0x00, 0x34, 0x90, 0x0e, 0xae, 0x60, 0x09, 0x00, - 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// QueryClient is the client API for Query service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type QueryClient interface { - // Params defines a gRPC query method that returns the tokenfactory module's - // parameters. - Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) - // DenomAuthorityMetadata defines a gRPC query method for fetching - // DenomAuthorityMetadata for a particular denom. - DenomAuthorityMetadata(ctx context.Context, in *QueryDenomAuthorityMetadataRequest, opts ...grpc.CallOption) (*QueryDenomAuthorityMetadataResponse, error) - // DenomsMetadata defines a gRPC query method for fetching - // DenomMetadata for a particular denom. - DenomMetadata(ctx context.Context, in *QueryDenomMetadataRequest, opts ...grpc.CallOption) (*QueryDenomMetadataResponse, error) - // DenomsFromCreator defines a gRPC query method for fetching all - // denominations created by a specific admin/creator. - DenomsFromCreator(ctx context.Context, in *QueryDenomsFromCreatorRequest, opts ...grpc.CallOption) (*QueryDenomsFromCreatorResponse, error) - // DenomAllowList defines a gRPC query method for fetching the denom allow list - DenomAllowList(ctx context.Context, in *QueryDenomAllowListRequest, opts ...grpc.CallOption) (*QueryDenomAllowListResponse, error) -} - -type queryClient struct { - cc grpc1.ClientConn -} - -func NewQueryClient(cc grpc1.ClientConn) QueryClient { - return &queryClient{cc} -} - -func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { - out := new(QueryParamsResponse) - err := c.cc.Invoke(ctx, "/seiprotocol.seichain.tokenfactory.Query/Params", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *queryClient) DenomAuthorityMetadata(ctx context.Context, in *QueryDenomAuthorityMetadataRequest, opts ...grpc.CallOption) (*QueryDenomAuthorityMetadataResponse, error) { - out := new(QueryDenomAuthorityMetadataResponse) - err := c.cc.Invoke(ctx, "/seiprotocol.seichain.tokenfactory.Query/DenomAuthorityMetadata", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *queryClient) DenomMetadata(ctx context.Context, in *QueryDenomMetadataRequest, opts ...grpc.CallOption) (*QueryDenomMetadataResponse, error) { - out := new(QueryDenomMetadataResponse) - err := c.cc.Invoke(ctx, "/seiprotocol.seichain.tokenfactory.Query/DenomMetadata", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *queryClient) DenomsFromCreator(ctx context.Context, in *QueryDenomsFromCreatorRequest, opts ...grpc.CallOption) (*QueryDenomsFromCreatorResponse, error) { - out := new(QueryDenomsFromCreatorResponse) - err := c.cc.Invoke(ctx, "/seiprotocol.seichain.tokenfactory.Query/DenomsFromCreator", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *queryClient) DenomAllowList(ctx context.Context, in *QueryDenomAllowListRequest, opts ...grpc.CallOption) (*QueryDenomAllowListResponse, error) { - out := new(QueryDenomAllowListResponse) - err := c.cc.Invoke(ctx, "/seiprotocol.seichain.tokenfactory.Query/DenomAllowList", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// QueryServer is the server API for Query service. -type QueryServer interface { - // Params defines a gRPC query method that returns the tokenfactory module's - // parameters. - Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) - // DenomAuthorityMetadata defines a gRPC query method for fetching - // DenomAuthorityMetadata for a particular denom. - DenomAuthorityMetadata(context.Context, *QueryDenomAuthorityMetadataRequest) (*QueryDenomAuthorityMetadataResponse, error) - // DenomsMetadata defines a gRPC query method for fetching - // DenomMetadata for a particular denom. - DenomMetadata(context.Context, *QueryDenomMetadataRequest) (*QueryDenomMetadataResponse, error) - // DenomsFromCreator defines a gRPC query method for fetching all - // denominations created by a specific admin/creator. - DenomsFromCreator(context.Context, *QueryDenomsFromCreatorRequest) (*QueryDenomsFromCreatorResponse, error) - // DenomAllowList defines a gRPC query method for fetching the denom allow list - DenomAllowList(context.Context, *QueryDenomAllowListRequest) (*QueryDenomAllowListResponse, error) -} - -// UnimplementedQueryServer can be embedded to have forward compatible implementations. -type UnimplementedQueryServer struct { -} - -func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") -} -func (*UnimplementedQueryServer) DenomAuthorityMetadata(ctx context.Context, req *QueryDenomAuthorityMetadataRequest) (*QueryDenomAuthorityMetadataResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method DenomAuthorityMetadata not implemented") -} -func (*UnimplementedQueryServer) DenomMetadata(ctx context.Context, req *QueryDenomMetadataRequest) (*QueryDenomMetadataResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method DenomMetadata not implemented") -} -func (*UnimplementedQueryServer) DenomsFromCreator(ctx context.Context, req *QueryDenomsFromCreatorRequest) (*QueryDenomsFromCreatorResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method DenomsFromCreator not implemented") -} -func (*UnimplementedQueryServer) DenomAllowList(ctx context.Context, req *QueryDenomAllowListRequest) (*QueryDenomAllowListResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method DenomAllowList not implemented") -} - -func RegisterQueryServer(s grpc1.Server, srv QueryServer) { - s.RegisterService(&_Query_serviceDesc, srv) -} - -func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryParamsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).Params(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/seiprotocol.seichain.tokenfactory.Query/Params", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Query_DenomAuthorityMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryDenomAuthorityMetadataRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).DenomAuthorityMetadata(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/seiprotocol.seichain.tokenfactory.Query/DenomAuthorityMetadata", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).DenomAuthorityMetadata(ctx, req.(*QueryDenomAuthorityMetadataRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Query_DenomMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryDenomMetadataRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).DenomMetadata(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/seiprotocol.seichain.tokenfactory.Query/DenomMetadata", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).DenomMetadata(ctx, req.(*QueryDenomMetadataRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Query_DenomsFromCreator_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryDenomsFromCreatorRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).DenomsFromCreator(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/seiprotocol.seichain.tokenfactory.Query/DenomsFromCreator", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).DenomsFromCreator(ctx, req.(*QueryDenomsFromCreatorRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Query_DenomAllowList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryDenomAllowListRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).DenomAllowList(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/seiprotocol.seichain.tokenfactory.Query/DenomAllowList", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).DenomAllowList(ctx, req.(*QueryDenomAllowListRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Query_serviceDesc = grpc.ServiceDesc{ - ServiceName: "seiprotocol.seichain.tokenfactory.Query", - HandlerType: (*QueryServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Params", - Handler: _Query_Params_Handler, - }, - { - MethodName: "DenomAuthorityMetadata", - Handler: _Query_DenomAuthorityMetadata_Handler, - }, - { - MethodName: "DenomMetadata", - Handler: _Query_DenomMetadata_Handler, - }, - { - MethodName: "DenomsFromCreator", - Handler: _Query_DenomsFromCreator_Handler, - }, - { - MethodName: "DenomAllowList", - Handler: _Query_DenomAllowList_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "tokenfactory/query.proto", -} - -func (m *QueryParamsRequest) 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 *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func (m *QueryParamsResponse) 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 *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *QueryDenomAuthorityMetadataRequest) 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 *QueryDenomAuthorityMetadataRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryDenomAuthorityMetadataRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Denom) > 0 { - i -= len(m.Denom) - copy(dAtA[i:], m.Denom) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Denom))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *QueryDenomAuthorityMetadataResponse) 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 *QueryDenomAuthorityMetadataResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryDenomAuthorityMetadataResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.AuthorityMetadata.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *QueryDenomsFromCreatorRequest) 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 *QueryDenomsFromCreatorRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryDenomsFromCreatorRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Pagination != nil { - { - size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.Creator) > 0 { - i -= len(m.Creator) - copy(dAtA[i:], m.Creator) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Creator))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *QueryDenomsFromCreatorResponse) 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 *QueryDenomsFromCreatorResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryDenomsFromCreatorResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Pagination != nil { - { - size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.Denoms) > 0 { - for iNdEx := len(m.Denoms) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Denoms[iNdEx]) - copy(dAtA[i:], m.Denoms[iNdEx]) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Denoms[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *QueryDenomMetadataRequest) 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 *QueryDenomMetadataRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryDenomMetadataRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Denom) > 0 { - i -= len(m.Denom) - copy(dAtA[i:], m.Denom) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Denom))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *QueryDenomMetadataResponse) 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 *QueryDenomMetadataResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryDenomMetadataResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *QueryDenomAllowListRequest) 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 *QueryDenomAllowListRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryDenomAllowListRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Denom) > 0 { - i -= len(m.Denom) - copy(dAtA[i:], m.Denom) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Denom))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *QueryDenomAllowListResponse) 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 *QueryDenomAllowListResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryDenomAllowListResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.AllowList.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { - offset -= sovQuery(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *QueryParamsRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *QueryParamsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovQuery(uint64(l)) - return n -} - -func (m *QueryDenomAuthorityMetadataRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Denom) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - return n -} - -func (m *QueryDenomAuthorityMetadataResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.AuthorityMetadata.Size() - n += 1 + l + sovQuery(uint64(l)) - return n -} - -func (m *QueryDenomsFromCreatorRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Creator) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) - } - return n -} - -func (m *QueryDenomsFromCreatorResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Denoms) > 0 { - for _, s := range m.Denoms { - l = len(s) - n += 1 + l + sovQuery(uint64(l)) - } - } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) - } - return n -} - -func (m *QueryDenomMetadataRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Denom) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - return n -} - -func (m *QueryDenomMetadataResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Metadata.Size() - n += 1 + l + sovQuery(uint64(l)) - return n -} - -func (m *QueryDenomAllowListRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Denom) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - return n -} - -func (m *QueryDenomAllowListResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.AllowList.Size() - n += 1 + l + sovQuery(uint64(l)) - return n -} - -func sovQuery(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozQuery(x uint64) (n int) { - return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *QueryParamsRequest) 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 ErrIntOverflowQuery - } - 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: QueryParamsRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryParamsResponse) 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 ErrIntOverflowQuery - } - 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: QueryParamsResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryDenomAuthorityMetadataRequest) 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 ErrIntOverflowQuery - } - 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: QueryDenomAuthorityMetadataRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryDenomAuthorityMetadataRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Denom = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryDenomAuthorityMetadataResponse) 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 ErrIntOverflowQuery - } - 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: QueryDenomAuthorityMetadataResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryDenomAuthorityMetadataResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AuthorityMetadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.AuthorityMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryDenomsFromCreatorRequest) 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 ErrIntOverflowQuery - } - 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: QueryDenomsFromCreatorRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryDenomsFromCreatorRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Creator = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pagination == nil { - m.Pagination = &query.PageRequest{} - } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryDenomsFromCreatorResponse) 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 ErrIntOverflowQuery - } - 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: QueryDenomsFromCreatorResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryDenomsFromCreatorResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Denoms", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Denoms = append(m.Denoms, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pagination == nil { - m.Pagination = &query.PageResponse{} - } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryDenomMetadataRequest) 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 ErrIntOverflowQuery - } - 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: QueryDenomMetadataRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryDenomMetadataRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Denom = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryDenomMetadataResponse) 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 ErrIntOverflowQuery - } - 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: QueryDenomMetadataResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryDenomMetadataResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryDenomAllowListRequest) 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 ErrIntOverflowQuery - } - 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: QueryDenomAllowListRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryDenomAllowListRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Denom = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryDenomAllowListResponse) 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 ErrIntOverflowQuery - } - 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: QueryDenomAllowListResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryDenomAllowListResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowList", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.AllowList.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipQuery(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, ErrIntOverflowQuery - } - 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, ErrIntOverflowQuery - } - 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, ErrIntOverflowQuery - } - 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, ErrInvalidLengthQuery - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupQuery - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthQuery - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/tokenfactory/types/query.pb.gw.go b/x/tokenfactory/types/query.pb.gw.go deleted file mode 100644 index 424ea3ee04..0000000000 --- a/x/tokenfactory/types/query.pb.gw.go +++ /dev/null @@ -1,539 +0,0 @@ -// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: tokenfactory/query.proto - -/* -Package types is a reverse proxy. - -It translates gRPC into RESTful JSON APIs. -*/ -package types - -import ( - "context" - "io" - "net/http" - - "github.com/golang/protobuf/descriptor" - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" -) - -// Suppress "imported and not used" errors -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray -var _ = descriptor.ForMessage -var _ = metadata.Join - -func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryParamsRequest - var metadata runtime.ServerMetadata - - msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryParamsRequest - var metadata runtime.ServerMetadata - - msg, err := server.Params(ctx, &protoReq) - return msg, metadata, err - -} - -func request_Query_DenomAuthorityMetadata_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryDenomAuthorityMetadataRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["denom"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom") - } - - protoReq.Denom, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err) - } - - msg, err := client.DenomAuthorityMetadata(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Query_DenomAuthorityMetadata_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryDenomAuthorityMetadataRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["denom"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom") - } - - protoReq.Denom, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err) - } - - msg, err := server.DenomAuthorityMetadata(ctx, &protoReq) - return msg, metadata, err - -} - -var ( - filter_Query_DenomMetadata_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} -) - -func request_Query_DenomMetadata_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryDenomMetadataRequest - var metadata runtime.ServerMetadata - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_DenomMetadata_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.DenomMetadata(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Query_DenomMetadata_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryDenomMetadataRequest - var metadata runtime.ServerMetadata - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_DenomMetadata_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := server.DenomMetadata(ctx, &protoReq) - return msg, metadata, err - -} - -var ( - filter_Query_DenomsFromCreator_0 = &utilities.DoubleArray{Encoding: map[string]int{"creator": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} -) - -func request_Query_DenomsFromCreator_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryDenomsFromCreatorRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["creator"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "creator") - } - - protoReq.Creator, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "creator", err) - } - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_DenomsFromCreator_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.DenomsFromCreator(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Query_DenomsFromCreator_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryDenomsFromCreatorRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["creator"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "creator") - } - - protoReq.Creator, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "creator", err) - } - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_DenomsFromCreator_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := server.DenomsFromCreator(ctx, &protoReq) - return msg, metadata, err - -} - -var ( - filter_Query_DenomAllowList_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} -) - -func request_Query_DenomAllowList_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryDenomAllowListRequest - var metadata runtime.ServerMetadata - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_DenomAllowList_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.DenomAllowList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Query_DenomAllowList_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryDenomAllowListRequest - var metadata runtime.ServerMetadata - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_DenomAllowList_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := server.DenomAllowList(ctx, &protoReq) - return msg, metadata, err - -} - -// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". -// UnaryRPC :call QueryServer directly. -// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. -func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { - - mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Query_DenomAuthorityMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Query_DenomAuthorityMetadata_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_DenomAuthorityMetadata_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Query_DenomMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Query_DenomMetadata_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_DenomMetadata_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Query_DenomsFromCreator_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Query_DenomsFromCreator_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_DenomsFromCreator_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Query_DenomAllowList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Query_DenomAllowList_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_DenomAllowList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterQueryHandler(ctx, mux, conn) -} - -// RegisterQueryHandler registers the http handlers for service Query to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) -} - -// RegisterQueryHandlerClient registers the http handlers for service Query -// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". -// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" -// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "QueryClient" to call the correct interceptors. -func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { - - mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Query_DenomAuthorityMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Query_DenomAuthorityMetadata_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_DenomAuthorityMetadata_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Query_DenomMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Query_DenomMetadata_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_DenomMetadata_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Query_DenomsFromCreator_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Query_DenomsFromCreator_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_DenomsFromCreator_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Query_DenomAllowList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Query_DenomAllowList_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_DenomAllowList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"sei-protocol", "seichain", "tokenfactory", "params"}, "", runtime.AssumeColonVerbOpt(false))) - - pattern_Query_DenomAuthorityMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"sei-protocol", "seichain", "tokenfactory", "denoms", "denom", "authority_metadata"}, "", runtime.AssumeColonVerbOpt(false))) - - pattern_Query_DenomMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"sei-protocol", "seichain", "tokenfactory", "denoms", "metadata"}, "", runtime.AssumeColonVerbOpt(false))) - - pattern_Query_DenomsFromCreator_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"sei-protocol", "seichain", "tokenfactory", "denoms_from_creator", "creator"}, "", runtime.AssumeColonVerbOpt(false))) - - pattern_Query_DenomAllowList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"sei-protocol", "seichain", "tokenfactory", "denoms", "allow_list"}, "", runtime.AssumeColonVerbOpt(false))) -) - -var ( - forward_Query_Params_0 = runtime.ForwardResponseMessage - - forward_Query_DenomAuthorityMetadata_0 = runtime.ForwardResponseMessage - - forward_Query_DenomMetadata_0 = runtime.ForwardResponseMessage - - forward_Query_DenomsFromCreator_0 = runtime.ForwardResponseMessage - - forward_Query_DenomAllowList_0 = runtime.ForwardResponseMessage -)