From 151fae914deb8e86bae3bb2d78c3feeebad0d81d Mon Sep 17 00:00:00 2001 From: alexander-sei Date: Tue, 13 Oct 2026 10:58:16 +0200 Subject: [PATCH 1/4] Remove the tokenfactory module behind the v6.8 upgrade Delete x/tokenfactory and proto/tokenfactory, unwire the module from the app, and delete the tokenfactory store and version-map entry at the v6.8 upgrade. The six Msg types move to a decode-only app/retiredtokenfactory package so historical transactions still decode; new ones are refused at CheckTx. Remove the factory/ denom transfer allowlist from the sei-cosmos and giga bank keepers and prune the stored allowlists at v6.8. Drop the tokenfactory wasm custom messages and query route, the tooling entries, and the tests and CI fixtures that created tokenfactory denoms. Co-authored-by: Cursor --- .../workflows/integration-test-matrix.json | 3 +- CHANGELOG.md | 1 + app/app.go | 26 +- app/apptesting/test_suite.go | 5 - app/encoding.go | 5 + .../retiredtokenfactory}/codec.go | 40 +- app/retiredtokenfactory/errors.go | 6 + app/retiredtokenfactory/msgs.go | 107 + .../retiredtokenfactory_test.go | 202 ++ .../retiredtokenfactory}/tx.pb.go | 274 +- .../upgrade_v68_offline_source_test.go | 25 +- app/upgrade_v68_offline_target_test.go | 52 +- app/upgrade_v68_test.go | 162 +- app/upgrades.go | 14 +- contracts/test/EVMPrecompileTest.js | 7 +- contracts/test/lib.js | 48 - evmrpc/tests/regression_test.go | 12 +- giga/deps/xbank/keeper/keeper_test.go | 198 -- giga/deps/xbank/keeper/send.go | 88 - giga/deps/xbank/types/key.go | 15 +- .../generic_authorization_test.yaml | 33 +- .../contracts/create_tokenfactory_denoms.sh | 90 - integration_test/dapp_tests/utils.js | 8 - .../precompile_tests/precompiles/bank.spec.ts | 44 +- .../precompiles/pointer.spec.ts | 15 +- .../precompile_tests/utils/cosmosUtils.ts | 45 +- integration_test/runner/runner_test.go | 6 +- integration_test/seidb/state_store_test.yaml | 40 - .../create_tokenfactory_test.yaml | 51 - loadtest/loadtest_client.go | 3 - loadtest/main.go | 26 - loadtest/types.go | 1 - proto/tokenfactory/authority_metadata.proto | 16 - proto/tokenfactory/genesis.proto | 32 - proto/tokenfactory/params.proto | 9 - proto/tokenfactory/query.proto | 107 - proto/tokenfactory/tx.proto | 106 - scripts/dump_app_state_for_height.sh | 2 +- sei-cosmos/x/bank/app_test.go | 374 --- sei-cosmos/x/bank/keeper/keeper_test.go | 338 --- sei-cosmos/x/bank/keeper/msg_server.go | 14 +- sei-cosmos/x/bank/keeper/send.go | 88 - sei-cosmos/x/bank/types/key.go | 15 +- sei-db/common/keys/store_keys.go | 2 - sei-db/tools/cmd/seidb/operations/module.go | 2 +- tools/utils/helper.go | 4 +- wasmbinding/bindings/msg.go | 30 - wasmbinding/encoder.go | 16 - wasmbinding/queries.go | 52 +- wasmbinding/query_plugin.go | 9 +- wasmbinding/test/encoder_test.go | 104 +- wasmbinding/test/query_test.go | 84 +- wasmbinding/wasm.go | 6 +- x/tokenfactory/README.md | 181 -- x/tokenfactory/client/cli/query.go | 129 - x/tokenfactory/client/cli/tx.go | 357 --- x/tokenfactory/client/cli/tx_test.go | 294 --- .../client/wasm/bindings/queries.go | 10 - x/tokenfactory/client/wasm/encoder.go | 70 - x/tokenfactory/client/wasm/query.go | 27 - x/tokenfactory/keeper/admins.go | 49 - x/tokenfactory/keeper/admins_test.go | 296 --- x/tokenfactory/keeper/bankactions.go | 58 - x/tokenfactory/keeper/bankactions_test.go | 209 -- x/tokenfactory/keeper/createdenom.go | 113 - x/tokenfactory/keeper/createdenom_test.go | 290 --- x/tokenfactory/keeper/creators.go | 41 - x/tokenfactory/keeper/genesis.go | 30 - x/tokenfactory/keeper/genesis_test.go | 58 - x/tokenfactory/keeper/grpc_query.go | 79 - x/tokenfactory/keeper/grpc_query_test.go | 273 -- x/tokenfactory/keeper/keeper.go | 80 - x/tokenfactory/keeper/keeper_test.go | 64 - x/tokenfactory/keeper/migrations.go | 79 - x/tokenfactory/keeper/migrations_test.go | 130 - x/tokenfactory/keeper/msg_server.go | 217 -- x/tokenfactory/keeper/params.go | 18 - x/tokenfactory/module.go | 170 -- x/tokenfactory/types/authority_metadata.go | 15 - x/tokenfactory/types/authority_metadata.pb.go | 349 --- x/tokenfactory/types/denoms.go | 84 - x/tokenfactory/types/denoms_test.go | 153 -- x/tokenfactory/types/errors.go | 34 - x/tokenfactory/types/events.go | 19 - x/tokenfactory/types/expected_keepers.go | 42 - x/tokenfactory/types/genesis.go | 51 - x/tokenfactory/types/genesis.pb.go | 647 ----- x/tokenfactory/types/genesis_test.go | 139 - x/tokenfactory/types/keys.go | 51 - x/tokenfactory/types/msgs.go | 237 -- x/tokenfactory/types/msgs_test.go | 362 --- x/tokenfactory/types/params.go | 46 - x/tokenfactory/types/params.pb.go | 301 --- x/tokenfactory/types/params_test.go | 155 -- x/tokenfactory/types/query.pb.go | 2236 ----------------- x/tokenfactory/types/query.pb.gw.go | 539 ---- 96 files changed, 678 insertions(+), 11166 deletions(-) rename {x/tokenfactory/types => app/retiredtokenfactory}/codec.go (57%) create mode 100644 app/retiredtokenfactory/errors.go create mode 100644 app/retiredtokenfactory/msgs.go create mode 100644 app/retiredtokenfactory/retiredtokenfactory_test.go rename {x/tokenfactory/types => app/retiredtokenfactory}/tx.pb.go (86%) delete mode 100755 integration_test/contracts/create_tokenfactory_denoms.sh delete mode 100644 integration_test/tokenfactory_module/create_tokenfactory_test.yaml delete mode 100644 proto/tokenfactory/authority_metadata.proto delete mode 100644 proto/tokenfactory/genesis.proto delete mode 100644 proto/tokenfactory/params.proto delete mode 100644 proto/tokenfactory/query.proto delete mode 100644 proto/tokenfactory/tx.proto delete mode 100644 x/tokenfactory/README.md delete mode 100644 x/tokenfactory/client/cli/query.go delete mode 100644 x/tokenfactory/client/cli/tx.go delete mode 100644 x/tokenfactory/client/cli/tx_test.go delete mode 100644 x/tokenfactory/client/wasm/bindings/queries.go delete mode 100644 x/tokenfactory/client/wasm/encoder.go delete mode 100644 x/tokenfactory/client/wasm/query.go delete mode 100644 x/tokenfactory/keeper/admins.go delete mode 100644 x/tokenfactory/keeper/admins_test.go delete mode 100644 x/tokenfactory/keeper/bankactions.go delete mode 100644 x/tokenfactory/keeper/bankactions_test.go delete mode 100644 x/tokenfactory/keeper/createdenom.go delete mode 100644 x/tokenfactory/keeper/createdenom_test.go delete mode 100644 x/tokenfactory/keeper/creators.go delete mode 100644 x/tokenfactory/keeper/genesis.go delete mode 100644 x/tokenfactory/keeper/genesis_test.go delete mode 100644 x/tokenfactory/keeper/grpc_query.go delete mode 100644 x/tokenfactory/keeper/grpc_query_test.go delete mode 100644 x/tokenfactory/keeper/keeper.go delete mode 100644 x/tokenfactory/keeper/keeper_test.go delete mode 100644 x/tokenfactory/keeper/migrations.go delete mode 100644 x/tokenfactory/keeper/migrations_test.go delete mode 100644 x/tokenfactory/keeper/msg_server.go delete mode 100644 x/tokenfactory/keeper/params.go delete mode 100644 x/tokenfactory/module.go delete mode 100644 x/tokenfactory/types/authority_metadata.go delete mode 100644 x/tokenfactory/types/authority_metadata.pb.go delete mode 100644 x/tokenfactory/types/denoms.go delete mode 100644 x/tokenfactory/types/denoms_test.go delete mode 100644 x/tokenfactory/types/errors.go delete mode 100644 x/tokenfactory/types/events.go delete mode 100644 x/tokenfactory/types/expected_keepers.go delete mode 100644 x/tokenfactory/types/genesis.go delete mode 100644 x/tokenfactory/types/genesis.pb.go delete mode 100644 x/tokenfactory/types/genesis_test.go delete mode 100644 x/tokenfactory/types/keys.go delete mode 100644 x/tokenfactory/types/msgs.go delete mode 100644 x/tokenfactory/types/msgs_test.go delete mode 100644 x/tokenfactory/types/params.go delete mode 100644 x/tokenfactory/types/params.pb.go delete mode 100644 x/tokenfactory/types/params_test.go delete mode 100644 x/tokenfactory/types/query.pb.go delete mode 100644 x/tokenfactory/types/query.pb.gw.go 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..640406e1b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## Unreleased sei-chain +* Remove the tokenfactory module behind the v6.8 upgrade: module, store, 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 and remain transferable, but can no longer be minted or burned. 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..d72dd3045a 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" @@ -47,13 +48,14 @@ var v68OfflineSourceStores = []string{authtypes.StoreKey, "bank", "gov", "upgrad // 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..0751971c82 100644 --- a/app/upgrade_v68_offline_target_test.go +++ b/app/upgrade_v68_offline_target_test.go @@ -40,10 +40,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 +134,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 and the denom allowlists 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 +145,7 @@ 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]) requireV68OfflineVoucher(t, testApp, artifact.Retained) requireOfflineUpgradeRetainedStoresExcept(t, testApp, artifact.Stores, v68OfflineTouchedKey(t, artifact)) } @@ -152,8 +153,8 @@ 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 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 +175,7 @@ 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, denomAllowListPrefix) } return false } @@ -248,11 +249,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 +312,33 @@ 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, 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, denomAllowListPrefix) + defer func() { + require.NoError(t, iterator.Close()) + }() + require.False(t, iterator.Valid(), "v6.8 left a denom allowlist in the bank store") +} + func requireV68OfflineVoucher(t *testing.T, testApp *App, retained offlineUpgradeRetainedState) { t.Helper() ctx, _ := offlineUpgradeReadContext(testApp, testApp.LastBlockHeight()).CacheContext() @@ -524,6 +554,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 +580,7 @@ func testV68OfflineUpgradeTargetSnapshot(t *testing.T) { defer closeOfflineUpgradeApp(t, reopened) requireV68OfflineVersionMap(t, reopened, beforeVersions) requireV68OfflineNoRetiredProposals(t, reopened) + requireV68OfflineNoDenomAllowLists(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..28010cda5e 100644 --- a/app/upgrade_v68_test.go +++ b/app/upgrade_v68_test.go @@ -11,6 +11,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,6 +19,7 @@ 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" upgradetypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/upgrade/types" abci "github.com/sei-protocol/sei-chain/sei-tendermint/abci/types" @@ -28,18 +30,19 @@ 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 and the denom +// transfer allowlists tokenfactory kept in the bank 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 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 +52,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 +110,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) } @@ -238,14 +245,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 +397,121 @@ 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)) +} + // 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 +648,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 +698,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 +717,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..9be28541f8 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -7,9 +7,11 @@ 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" upgradetypes "github.com/sei-protocol/sei-chain/sei-cosmos/x/upgrade/types" "golang.org/x/mod/semver" @@ -22,7 +24,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...) + +// denomAllowListPrefix is the bank-store prefix under which tokenfactory kept +// the transfer allowlists of the denoms it created. +var denomAllowListPrefix = []byte{0x11} // retiredIBCProposalTypeURLPrefix matches governance proposal content types // whose decoders no longer exist. @@ -156,6 +162,7 @@ func (app *App) RegisterUpgradeHandlers() { app.UpgradeKeeper.DeleteModuleVersion(ctx, feegrantModuleName) app.UpgradeKeeper.DeleteModuleVersion(ctx, vestingModuleName) app.pruneUpgradedIBCState(ctx) + app.pruneDenomAllowLists(ctx) return newVM, nil } @@ -246,6 +253,11 @@ func (app *App) pruneUpgradedIBCState(ctx sdk.Context) { deleteByPrefix(ctx.KVStore(app.GetKey(upgradetypes.StoreKey)), []byte(upgradedIBCStateKeyPrefix)) } +// pruneDenomAllowLists removes every denom transfer allowlist from the bank store. +func (app *App) pruneDenomAllowLists(ctx sdk.Context) { + deleteByPrefix(ctx.KVStore(app.GetKey(banktypes.StoreKey)), denomAllowListPrefix) +} + func deleteByPrefix(store sdk.KVStore, prefix []byte) { iterator := sdk.KVStorePrefixIterator(store, prefix) var keys [][]byte 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..60f4daec7a 100644 --- a/evmrpc/tests/regression_test.go +++ b/evmrpc/tests/regression_test.go @@ -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..a53f11186c 100644 --- a/giga/deps/xbank/keeper/keeper_test.go +++ b/giga/deps/xbank/keeper/keeper_test.go @@ -46,10 +46,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 +286,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 +412,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/key.go b/giga/deps/xbank/types/key.go index bc55c3bdb8..abaff24778 100644 --- a/giga/deps/xbank/types/key.go +++ b/giga/deps/xbank/types/key.go @@ -28,11 +28,10 @@ var ( WeiBalancesPrefix = []byte{0x04} // BalancesPrefix is the prefix for the account balances store. We use a byte // (instead of `[]byte("balances")` to save some disk space). - DeferredCachePrefix = []byte{0x03} - BalancesPrefix = []byte{0x02} - SupplyKey = []byte{0x00} - DenomMetadataPrefix = []byte{0x1} - DenomAllowListPrefix = []byte{0x11} + DeferredCachePrefix = []byte{0x03} + BalancesPrefix = []byte{0x02} + SupplyKey = []byte{0x00} + DenomMetadataPrefix = []byte{0x1} ) // DenomMetadataKey returns the denomination metadata key. @@ -41,12 +40,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/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..0ebc894c2b 100644 --- a/sei-cosmos/x/bank/keeper/keeper_test.go +++ b/sei-cosmos/x/bank/keeper/keeper_test.go @@ -48,10 +48,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 +556,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 +1257,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/key.go b/sei-cosmos/x/bank/types/key.go index bc55c3bdb8..abaff24778 100644 --- a/sei-cosmos/x/bank/types/key.go +++ b/sei-cosmos/x/bank/types/key.go @@ -28,11 +28,10 @@ var ( WeiBalancesPrefix = []byte{0x04} // BalancesPrefix is the prefix for the account balances store. We use a byte // (instead of `[]byte("balances")` to save some disk space). - DeferredCachePrefix = []byte{0x03} - BalancesPrefix = []byte{0x02} - SupplyKey = []byte{0x00} - DenomMetadataPrefix = []byte{0x1} - DenomAllowListPrefix = []byte{0x11} + DeferredCachePrefix = []byte{0x03} + BalancesPrefix = []byte{0x02} + SupplyKey = []byte{0x00} + DenomMetadataPrefix = []byte{0x1} ) // DenomMetadataKey returns the denomination metadata key. @@ -41,12 +40,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 -) From f7f6de25b8a32f86e8e30bcc747638bdda853a77 Mon Sep 17 00:00:00 2001 From: alexander-sei Date: Tue, 13 Oct 2026 10:59:17 +0200 Subject: [PATCH 2/4] Link the tokenfactory CHANGELOG entry to its PR Co-authored-by: Cursor --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 640406e1b9..0eda146933 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## Unreleased sei-chain -* Remove the tokenfactory module behind the v6.8 upgrade: module, store, 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 and remain transferable, but can no longer be minted or burned. App-hash breaking at the upgrade height. +* [#4536](https://github.com/sei-protocol/sei-chain/pull/4536) Remove the tokenfactory module behind the v6.8 upgrade: module, store, 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 and remain transferable, but can no longer be minted or burned. 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 From 286909ff603b1abf96fd122cde72e3d1df89b0b8 Mon Sep 17 00:00:00 2001 From: alexander-sei Date: Tue, 13 Oct 2026 20:03:21 +0200 Subject: [PATCH 3/4] Prune tokenfactory params at v6.8 and drop its leftovers The v6.8 handler now also deletes the tokenfactory parameter subspace from the params store, so none of the module's state outlives it. The in-process test seeds the parameter v6.7 keeps and a creation fee an older version left behind, and the offline fixture adds the params store to its retained-store snapshot, so a v6.7-written database shows the prune touches nothing else. Drop the unused AllowList copy from giga's bank.pb.go. Its embedded descriptor is left as is: it registers under the same file name as the sei-cosmos descriptor, which still has to describe AllowList for the retired tokenfactory messages. Also correct the AllowList field comment, delete the factoryDenomPrefix constants only the removed allowlist tests used, and mark the 0xc2da regression fixture as a revert, which it has traced as since #4202. Co-authored-by: Cursor --- CHANGELOG.md | 2 +- .../upgrade_v68_offline_source_test.go | 2 +- app/upgrade_v68_offline_target_test.go | 43 +++- app/upgrade_v68_test.go | 51 ++++- app/upgrades.go | 11 + evmrpc/tests/regression_test.go | 2 +- giga/deps/xbank/keeper/keeper_test.go | 13 +- giga/deps/xbank/types/bank.pb.go | 204 ------------------ .../proto/cosmos/bank/v1beta1/bank.proto | 2 +- sei-cosmos/x/bank/keeper/keeper_test.go | 13 +- sei-cosmos/x/bank/types/bank.pb.go | 2 +- 11 files changed, 109 insertions(+), 236 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0eda146933..c08afa7fff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +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, 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 and remain transferable, but can no longer be minted or burned. App-hash breaking at the upgrade height. +* [#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 and remain transferable, but can no longer be minted or burned. 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/testdata/upgrade_v68_offline_source_test.go b/app/testdata/upgrade_v68_offline_source_test.go index d72dd3045a..1a37886a41 100644 --- a/app/testdata/upgrade_v68_offline_source_test.go +++ b/app/testdata/upgrade_v68_offline_source_test.go @@ -44,7 +44,7 @@ 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. diff --git a/app/upgrade_v68_offline_target_test.go b/app/upgrade_v68_offline_target_test.go index 0751971c82..a49b431028 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" @@ -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 and the denom allowlists are 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) @@ -146,6 +147,7 @@ func requireV68OfflineMigrated(t *testing.T, testApp *App, artifact offlineUpgra 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)) } @@ -153,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, the pruned denom allowlists, -// 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)) @@ -176,6 +179,8 @@ 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) || bytes.HasPrefix(key, denomAllowListPrefix) + case paramstypes.StoreKey: + return bytes.HasPrefix(key, tokenfactoryParamsPrefix) } return false } @@ -339,6 +344,33 @@ func requireV68OfflineNoDenomAllowLists(t *testing.T, testApp *App) { 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() @@ -581,6 +613,7 @@ func testV68OfflineUpgradeTargetSnapshot(t *testing.T) { 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 28010cda5e..82b28a941a 100644 --- a/app/upgrade_v68_test.go +++ b/app/upgrade_v68_test.go @@ -21,6 +21,7 @@ import ( 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" @@ -32,13 +33,14 @@ import ( // 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 and the denom -// transfer allowlists tokenfactory kept in the bank 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 pruning, -// genesis export over the migrated store, and the handler itself. +// 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. @@ -166,7 +168,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()) }() @@ -512,6 +521,32 @@ func TestV68SendsADenomItsAllowListRestricted(t *testing.T) { require.Equal(t, sdk.NewInt64Coin(denom, 60), a.BankKeeper.GetBalance(a.Ctx(), holder, denom)) } +// 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 diff --git a/app/upgrades.go b/app/upgrades.go index 9be28541f8..e6fc1a4978 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -13,6 +13,7 @@ import ( "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" @@ -30,6 +31,10 @@ var v68DeletedStores = append([]string{retiredoracle.ModuleName, retiredtokenfac // the transfer allowlists of the denoms it created. var denomAllowListPrefix = []byte{0x11} +// 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. const retiredIBCProposalTypeURLPrefix = "/ibc." @@ -163,6 +168,7 @@ func (app *App) RegisterUpgradeHandlers() { app.UpgradeKeeper.DeleteModuleVersion(ctx, vestingModuleName) app.pruneUpgradedIBCState(ctx) app.pruneDenomAllowLists(ctx) + app.pruneTokenfactoryParams(ctx) return newVM, nil } @@ -258,6 +264,11 @@ func (app *App) pruneDenomAllowLists(ctx sdk.Context) { deleteByPrefix(ctx.KVStore(app.GetKey(banktypes.StoreKey)), 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) +} + func deleteByPrefix(store sdk.KVStore, prefix []byte) { iterator := sdk.KVStorePrefixIterator(store, prefix) var keys [][]byte diff --git a/evmrpc/tests/regression_test.go b/evmrpc/tests/regression_test.go index 60f4daec7a..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, ) } diff --git a/giga/deps/xbank/keeper/keeper_test.go b/giga/deps/xbank/keeper/keeper_test.go index a53f11186c..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 ( 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/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/keeper/keeper_test.go b/sei-cosmos/x/bank/keeper/keeper_test.go index 0ebc894c2b..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 ( 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"` } From e964473c82c4f9179db0e54647d07657053f0149 Mon Sep 17 00:00:00 2001 From: alexander-sei Date: Thu, 15 Oct 2026 13:03:10 +0200 Subject: [PATCH 4/4] Bound the v6.8 denom allowlist prune Creating a tokenfactory denom allowlist costs only gas, and each one is a single bank key, even when the list is empty. The v6.8 handler deleted all of them in the upgrade block, so anyone could grow that work before the upgrade height. The delete held every key in memory and left every delete pending in the bank cache for the rest of the block, where each bank iterator a transaction opened had to scan them. deleteByPrefix, which every v6.8 prune goes through, now deletes at most RetiredPrefixDeleteLimit (1,000) keys in key order and leaves the rest. Nothing reads the allowlists after this change, so any that survive are inert. DenomAllowListPrefix is declared again in both bank key.go files, marked deprecated, so no later bank key reuses 0x11, and the app's private copy of the prefix is gone. TestV68DenomAllowListPruneIsBounded seeds one allowlist more than the limit and checks that only the last one survives and that it does not restrict a send of its denom. The CHANGELOG entry now says that denoms with an allowlist become freely transferable. At pacific-1 height 237,714,318 there are two allowlists and atlantic-2 has 36, so both networks still end up with none. Co-authored-by: Cursor --- CHANGELOG.md | 2 +- app/upgrade_v68_offline_target_test.go | 6 ++--- app/upgrade_v68_test.go | 37 ++++++++++++++++++++++++++ app/upgrades.go | 19 ++++++++----- giga/deps/xbank/types/key.go | 9 ++++--- sei-cosmos/x/bank/types/key.go | 9 ++++--- 6 files changed, 63 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c08afa7fff..e93e58046e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +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 and remain transferable, but can no longer be minted or burned. App-hash breaking at the upgrade height. +* [#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/upgrade_v68_offline_target_test.go b/app/upgrade_v68_offline_target_test.go index a49b431028..9ebe5e9b97 100644 --- a/app/upgrade_v68_offline_target_test.go +++ b/app/upgrade_v68_offline_target_test.go @@ -178,7 +178,7 @@ 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) || bytes.HasPrefix(key, denomAllowListPrefix) + return v68OfflineBlockRewardKey(key) || bytes.HasPrefix(key, banktypes.DenomAllowListPrefix) case paramstypes.StoreKey: return bytes.HasPrefix(key, tokenfactoryParamsPrefix) } @@ -326,7 +326,7 @@ func requireV68OfflineDenomAllowListsPruned(t *testing.T, testApp *App, sourceBa for encodedKey := range sourceBank { key, err := base64.StdEncoding.DecodeString(encodedKey) require.NoError(t, err) - recorded = recorded || bytes.HasPrefix(key, denomAllowListPrefix) + recorded = recorded || bytes.HasPrefix(key, banktypes.DenomAllowListPrefix) } require.True(t, recorded, "the source phase recorded no denom allowlist") requireV68OfflineNoDenomAllowLists(t, testApp) @@ -337,7 +337,7 @@ func requireV68OfflineDenomAllowListsPruned(t *testing.T, testApp *App, sourceBa func requireV68OfflineNoDenomAllowLists(t *testing.T, testApp *App) { t.Helper() store := testApp.CommitMultiStore().GetCommitKVStore(testApp.GetKey(banktypes.StoreKey)) - iterator := sdk.KVStorePrefixIterator(store, denomAllowListPrefix) + iterator := sdk.KVStorePrefixIterator(store, banktypes.DenomAllowListPrefix) defer func() { require.NoError(t, iterator.Close()) }() diff --git a/app/upgrade_v68_test.go b/app/upgrade_v68_test.go index 82b28a941a..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" @@ -521,6 +522,42 @@ func TestV68SendsADenomItsAllowListRestricted(t *testing.T) { 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 diff --git a/app/upgrades.go b/app/upgrades.go index e6fc1a4978..cdd0d07584 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -27,10 +27,6 @@ var retiredIBCStores = []string{"capability", "ibc", "transfer"} // upgrade height. Their module version map entries go with them. var v68DeletedStores = append([]string{retiredoracle.ModuleName, retiredtokenfactory.ModuleName}, retiredIBCStores...) -// denomAllowListPrefix is the bank-store prefix under which tokenfactory kept -// the transfer allowlists of the denoms it created. -var denomAllowListPrefix = []byte{0x11} - // tokenfactoryParamsPrefix is the params-store prefix of the tokenfactory // parameter subspace. var tokenfactoryParamsPrefix = []byte(retiredtokenfactory.ModuleName + "/") @@ -46,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/" @@ -259,9 +259,10 @@ func (app *App) pruneUpgradedIBCState(ctx sdk.Context) { deleteByPrefix(ctx.KVStore(app.GetKey(upgradetypes.StoreKey)), []byte(upgradedIBCStateKeyPrefix)) } -// pruneDenomAllowLists removes every denom transfer allowlist from the bank store. +// 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)), denomAllowListPrefix) + deleteByPrefix(ctx.KVStore(app.GetKey(banktypes.StoreKey)), banktypes.DenomAllowListPrefix) } // pruneTokenfactoryParams removes every parameter of the tokenfactory subspace from the params store. @@ -269,10 +270,14 @@ 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/giga/deps/xbank/types/key.go b/giga/deps/xbank/types/key.go index abaff24778..a4a1def783 100644 --- a/giga/deps/xbank/types/key.go +++ b/giga/deps/xbank/types/key.go @@ -28,10 +28,11 @@ var ( WeiBalancesPrefix = []byte{0x04} // BalancesPrefix is the prefix for the account balances store. We use a byte // (instead of `[]byte("balances")` to save some disk space). - DeferredCachePrefix = []byte{0x03} - BalancesPrefix = []byte{0x02} - SupplyKey = []byte{0x00} - DenomMetadataPrefix = []byte{0x1} + DeferredCachePrefix = []byte{0x03} + BalancesPrefix = []byte{0x02} + SupplyKey = []byte{0x00} + DenomMetadataPrefix = []byte{0x1} + DenomAllowListPrefix = []byte{0x11} // deprecated ) // DenomMetadataKey returns the denomination metadata key. diff --git a/sei-cosmos/x/bank/types/key.go b/sei-cosmos/x/bank/types/key.go index abaff24778..a4a1def783 100644 --- a/sei-cosmos/x/bank/types/key.go +++ b/sei-cosmos/x/bank/types/key.go @@ -28,10 +28,11 @@ var ( WeiBalancesPrefix = []byte{0x04} // BalancesPrefix is the prefix for the account balances store. We use a byte // (instead of `[]byte("balances")` to save some disk space). - DeferredCachePrefix = []byte{0x03} - BalancesPrefix = []byte{0x02} - SupplyKey = []byte{0x00} - DenomMetadataPrefix = []byte{0x1} + DeferredCachePrefix = []byte{0x03} + BalancesPrefix = []byte{0x02} + SupplyKey = []byte{0x00} + DenomMetadataPrefix = []byte{0x1} + DenomAllowListPrefix = []byte{0x11} // deprecated ) // DenomMetadataKey returns the denomination metadata key.