xanoutas/solidity-security-findings huggingface dataset:
An attacker can DoS a coinswap pool
Audit: 2024-05-canto-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/x/coinswap/keeper/keeper.go#L168


# Vulnerability details

## Impact

DOS of the pool

## Proof of Concept

The balance calculations are initiated by calling k.GetPoolBalances(ctx, pool.EscrowAddress), which internally calls the k.bk.GetAllBalances function. This function iterates through all token balances in a loop. If the array of tokens is excessively large, the function may fail due to insufficient gas.

In essence, if an attacker introduces a large number of tokens, for instance through the AddLiquidity process, and subsequently transfers these tokens to a target pool, it can lead to an exploit. The attacker can strategically overload the array, causing significant gas consumption and ultimately causing the function to fail.

The process is as follows: When the AddLiquidity or RemoveLiquidity functions are called within the coinswap module, the k.GetPoolBalances function retrieves the balance of all tokens in the pool. This function, k.GetPoolBalances, calls k.bk.GetAllBalances, which iterates through and aggregates all token balances before sorting them into an array.

Specifically, k.bk.GetAllBalances utilizes the following approach:

```go
func (k BaseViewKeeper) GetAllBalances(ctx context.Context, addr sdk.AccAddress) sdk.Coins {
    balances := sdk.NewCoins()
    k.IterateAccountBalances(ctx, addr, func(balance sdk.Coin) bool {
        balances = balances.Add(balance)
        return false
    })
    return balances.Sort()
}
```

Here, sdk.NewCoins() returns an array of type Coins.

When an attacker exploits the AddLiquidity function in the coinswap module, they can create a pool using k.CreatePool(ctx, msg.MaxToken.Denom) if the pool does not already exist. By generating a large number of tokens and sending them to the target pool, the attacker causes the array of balances returned by GetPoolBalances to become excessively large. This leads to high gas consumption and potential transaction failure due to insufficient gas, thus disrupting the functionality of the coinswap module.


## Tools Used

Eyes

## Recommended Mitigation Steps

Get only 1 token balance instead of all


## Assessed type

Other
MsgSwapOrder will never work for Canto nodes
Audit: 2024-05-canto-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/proto/canto/coinswap/v1/tx.proto#L96-L104


# Vulnerability details

## Impact

MsgSwapOrder will never work for Canto nodes

## Proof of Concept

An oversight in the ﻿[MsgSwapOrder](https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/proto/canto/coinswap/v1/tx.proto#L96-L104) where the tag is directed to nested ﻿Input message lacks the necessary ﻿cosmos.msg.v1.signer to indirectly identify the signer

```go
message Input {
  string address = 1;
  cosmos.base.v1beta1.Coin coin = 2 [ (gogoproto.nullable) = false ];
}
```

## Tools Used

Eyes

## Recommended Mitigation Steps

Add DefineCustomGetSigners call in app.go for the coinswap Input message like u did for MsgConvertERC20

https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/app/app.go#L316

```go
signingOptions.DefineCustomGetSigners(protov2.MessageName(&erc20v1.MsgConvertERC20{}), erc20types.GetSignersFromMsgConvertERC20V2)
```





## Assessed type

Other
Several Inconsistencies in `app.go` from cosmos 0.5.x upgrade
Audit: 2024-05-canto-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/app/app.go#L802


# Vulnerability details

## Impact
In order to ensure complete compatibility with cosmos 0.50.x, it is necessary to align with their code changes unless when not absolutely necessary. This report demonstrates some cases where this is not the case.

## Proof of Concept
According to the README under `Areas of Concern`, one of the important things to look for is 
- `Ensure compatibility with Cosmos-SDK v0.50.x and identify any breaking changes from v0.45.x.`

In the documentation of Cosmos 0.50.0. It is stated that it is no longer required to set modules in orderBeginBlockers and OrderEndBlockers. 

https://github.com/cosmos/cosmos-sdk/blob/v0.50.6/UPGRADING.md#module-assertions

However, this is still the case within Canto-main/app.go
```
@> app.ModuleManager.SetOrderBeginBlockers(
```
```
app.ModuleManager.SetOrderEndBlockers(
```

Also,
```
When using (legacy) application wiring, the following must be added to app.go:

+app.ModuleManager.SetOrderPreBlockers(
+	upgradetypes.ModuleName,
+)

app.ModuleManager.SetOrderBeginBlockers(
-	upgradetypes.ModuleName,
)

+ app.SetPreBlocker(app.PreBlocker)

// ... //

+func (app *SimApp) PreBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) {
+	return app.ModuleManager.PreBlock(ctx, req)
+}

```
This is however not implemented like it is stated here.

This demonstrates that there're several inconsistencies between the  new update and the recommended changes from Cosmos Sdk


## Tools Used
Manual Review

## Recommended Mitigation Steps
1. Align with the recommendations of Cosmos 0.50.x in the documentation
`https://github.com/cosmos/cosmos-sdk/blob/v0.50.6/UPGRADING.md#module-assertions`








## Assessed type

Other
tmbytes.HexBytes is not changed to []bytes cause incorrect interface GetDenomTrace implementation
Audit: 2024-05-canto-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/x/onboarding/types/interfaces.go#L70


# Vulnerability details

## Impact

tmbytes.HexBytes is not changed to []bytes cause incorrect interface implementation

## Proof of Concept

According to https://github.com/cosmos/cosmos-sdk/blob/v0.50.6/UPGRADING.md

> The usage of github.com/cometbft/cometbft/libs/bytes.HexByte has been replaced by []byte.

but in the current code, 

In [2024-05-canto/canto-main/x/onboarding/types/interfaces.go](https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/x/onboarding/types/interfaces.go#L70)

```solidity
// TransferKeeper defines the expected IBC transfer keeper.
type TransferKeeper interface {
	GetDenomTrace(ctx sdk.Context, denomTraceHash tmbytes.HexBytes) (transfertypes.DenomTrace, bool)
}
```

the link above explains how the donomTrace is used extensively in the codebase.

https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-001-coin-source-tracing.md#xibc-transfer-changes

```solidity
// GetDenomTrace retrieves the full identifiers trace and base denomination from the store.
func (k Keeper) GetDenomTrace(ctx Context, denomTraceHash []byte) (DenomTrace, bool) {
  store := ctx.KVStore(k.storeKey)
  bz := store.Get(types.KeyDenomTrace(traceHash))
  if bz == nil {
    return &DenomTrace, false
  }

  var denomTrace DenomTrace
  k.cdc.MustUnmarshalBinaryBare(bz, &denomTrace)
  return denomTrace, true
}

// HasDenomTrace checks if a the key with the given trace hash exists on the store.
func (k Keeper) HasDenomTrace(ctx Context, denomTraceHash []byte)  bool {
  store := ctx.KVStore(k.storeKey)
  return store.Has(types.KeyTrace(denomTraceHash))
}

// SetDenomTrace sets a new {trace hash -> trace} pair to the store.
func (k Keeper) SetDenomTrace(ctx Context, denomTrace DenomTrace) {
  store := ctx.KVStore(k.storeKey)
  bz := k.cdc.MustMarshalBinaryBare(&denomTrace)
  store.Set(types.KeyTrace(denomTrace.Hash()), bz)
}
```

and then

```solidity
// SendTransfer
// ...

  fullDenomPath := token.Denom

// deconstruct the token denomination into the denomination trace info
// to determine if the sender is the source chain
if strings.HasPrefix(token.Denom, "ibc/") {
@  fullDenomPath, err = k.DenomPathFromHash(ctx, token.Denom)
  if err != nil {
    return err
  }
}

if types.SenderChainIsSource(sourcePort, sourceChannel, fullDenomPath) {
//...
```

and

```solidity
// DenomPathFromHash returns the full denomination path prefix from an ibc denom with a hash
// component.
func (k Keeper) DenomPathFromHash(ctx sdk.Context, denom string) (string, error) {
  hexHash := denom[4:]
  hash, err := ParseHexHash(hexHash)
  if err != nil {
    return "", Wrap(ErrInvalidDenomForTransfer, err.Error())
  }

@  denomTrace, found := k.GetDenomTrace(ctx, hash)
  if !found {
    return "", Wrap(ErrTraceNotFound, hexHash)
  }

  fullDenomPath := denomTrace.GetFullDe
upgradetypes.ModuleName has been mistakenly added to SetOrderBeginBlockers
Audit: 2024-05-canto-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-05-canto/blob/main/canto-main/app/app.go#L823
https://github.com/code-423n4/2024-05-canto/blob/main/ethermint-main/app/app.go#L695


# Vulnerability details

## Description
According to the [upgrading guide](https://github.com/cosmos/cosmos-sdk/blob/v0.50.6/UPGRADING.md) of cosmos sdk for version 0.50.6, when using (legacy) application wiring, the following must be added to app.go:

````Solidity
+app.ModuleManager.SetOrderPreBlockers(
+	upgradetypes.ModuleName,
+)

app.ModuleManager.SetOrderBeginBlockers(
-	upgradetypes.ModuleName,
)

````

However, in the app.go of Canto and Ethermint, the upgradetypes.ModuleName under SetOrderBeginBlockers has not been removed.

````Solidity
Canto App
File: app.go
823: 		upgradetypes.ModuleName, //@audit should be removed? 

Ethermint App
File: app.go
668: 		upgradetypes.ModuleName,//@audit should be removed
````

## Impact
Running the same module twice in a single block cycle can introduce unnecessary computational overhead. This redundancy can slow down block processing without adding any benefit.

## Proof of Concept
Consider this scenario, in every block processing, upgradetypes.ModuleName  will be executed twice, one in preblock phase and one in beginblock phase. This will delay the overall performance of Canto blockchain as well as unnecessary consumption of resources. 

## Tools Used
Manual Review

## Recommended Mitigation Steps
Remove the upgradetypes.ModuleName under SetOrderBeginBlockers as per upgrade guide.


## Assessed type

Other
DoS vulnerability in `coinswap` pool
Audit: 2024-05-canto-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/x/coinswap/keeper/keeper.go#L168
https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/x/coinswap/keeper/keeper.go#L264-L265


# Vulnerability details

## Description
The balances are calculated from `k.GetPoolBalances(ctx, pool.EscrowAddress)` that actually calls the `k.bk.GetAllBalances` function.

This function loop through the balance of all the token in the loop. Ultimately, if the array is too large, the function can fail due to insufficient gas.

A malicious actor can create a large number of tokens using AddLiquidity for example.

He could then transfer these tokens to the target pool for an attack.


## Impact
This can cause a DoS.

## POC

```go
func (k Keeper) GetPoolBalances(ctx sdk.Context, escrowAddress string) (coins sdk.Coins, err error) {
	address, err := sdk.AccAddressFromBech32(escrowAddress)
	if err != nil {
		return coins, err
	}
	acc := k.ak.GetAccount(ctx, address)
	if acc == nil {
		return nil, errorsmod.Wrap(types.ErrReservePoolNotExists, escrowAddress)
	}
	return k.bk.GetAllBalances(ctx, acc.GetAddress()), nil
}
```
```go
func (k BaseViewKeeper) GetAllBalances(ctx context.Context, addr sdk.AccAddress) sdk.Coins {
	balances := sdk.NewCoins()
	k.IterateAccountBalances(ctx, addr, func(balance sdk.Coin) bool {
		balances = balances.Add(balance)
		return false
	})

	return balances.Sort()
}
```

## Tools Used
Manual review

## Recommended Mitigation
`bk.GetAllBalances` shouldn't be used to get the balances of all tokens. Instead, you need to have the balance of 1 token in the pool.




## Assessed type

DoS
`context.Context` should be used everywhere instead of `sdk.Context`. This can lead to incorrect interfaces.
Audit: 2024-05-canto-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/app/ante/interfaces.go#L13


# Vulnerability details

## Impact
sdk.Context is still used instead of context.Context, causing interface mismatch. I Won't go through all the instances in the project but there >400 places to update based on a vs code search for `sdk.context`

## Proof of Concept
More information can be found here: https://github.com/cosmos/cosmos-sdk/blob/v0.50.6/UPGRADING.md 

Specifically in the section Module.

## Tools Used

Manual review

## Recommended Mitigation Steps

Change sdk.Context to context.Context


## Assessed type

Other
Panic in MustUnmarshal
Audit: 2024-05-canto-findings
Severity: MEDIUM

# Lines of code

https://github.com/b-harvest/ethermint/blob/dudong2/feat/cosmos-sdk%40v0.50.x-cometbft%40v0.38.0-2/x/evm/types/msg.go#L464
https://github.com/b-harvest/ethermint/blob/dudong2/feat/cosmos-sdk%40v0.50.x-cometbft%40v0.38.0-2/x/evm/types/msg.go#L471
https://github.com/b-harvest/ethermint/blob/dudong2/feat/cosmos-sdk%40v0.50.x-cometbft%40v0.38.0-2/x/evm/types/msg.go#L478


# Vulnerability details

## Impact
The ModuleCdc is only strictly used for testing, as stated in https://github.com/b-harvest/ethermint/blob/dudong2/feat/cosmos-sdk%40v0.50.x-cometbft%40v0.38.0-2/x/evm/types/codec.go#L30-L32.

eventhough the usage of ModuleCdc itself is harmless, this can be used to DOS the node by leveraging the fact that MustUnmarshal is being used by ModuleCdc.

MustUnmarshal is very strict and it's going to panic when it fails to unmarshal the data, which we can see in this code https://github.com/cosmos/cosmos-sdk/blob/main/codec/proto_codec.go#L108-L115. 

## Proof of Concept
example snippet of the POC

"@type": "/ethermint.evm.v1.MsgEthereumTx",
            "data": {
              "@type": "/ethermint.evm.v1.DynamicFeeTx",
              //the data below is the legacyTX fields, However, we defined the @type as a DynamicFeeTx
              "nonce": "8",
              "gas_price": "7",
              "gas": "999999999999",
              "to": "0x60DD27A3FbB76e158F6e7EE4F1FB926a052CF2ab",
              "value": "0",
              "data": "qSEAyw==",
              "v": "BjY=",
              "r": "qaJ6tUAIqPQ/neu+fYXEeWoCJtwnssAd9jLbQ2ee/u4=",
              "s": "JFSlZnGfL/jqBnDjVvmqbGZ+Qt4Mnr03wqRIPKNALtM="
            },


## Tools Used
manual

## Recommended Mitigation Steps
as stated in the https://github.com/cosmos/cosmos-sdk/blob/main/codec/proto_codec.go#L108-L115. to dynamicly handle errors during  data unmarshaling, please use UnmarshalInterface function, and handle the error properly, instead of panicking.





## Assessed type

DoS
Protocol uses deprecated library
Audit: 2024-05-canto-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/go.mod#L32
https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/ethermint-main/x/feemarket/migrations/v4/types/feemarket.pb.go#L11


# Vulnerability details

## Impact

According to the v0.47.11 upgrade documents present at https://github.com/cosmos/cosmos-sdk/blob/v0.47.11/UPGRADING.md#protobuf,

```
The SDK has migrated from gogo/protobuf (which is currently unmaintained), to our own maintained fork, cosmos/gogoproto.

This means you should replace all imports of github.com/gogo/protobuf to github.com/cosmos/gogoproto. This allows you to remove the replace directive replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 from your go.mod file.

Please use the ghcr.io/cosmos/proto-builder image (version >= 0.11.5) for generating protobuf files.
```

However, the protocol still uses the deprecated `gogo/protobuf` library in multiple places. In the `ethermint-main/x/feemarket` module, the older protobuf version is used to do plenty of operations.

```go
func init() {
	proto.RegisterFile("ethermint/feemarket/v1/feemarket.proto", fileDescriptor_4feb8b20cf98e6e1)
}
```

The `gogo/protobuf` library is imported and used in lots of different locations in the codebase. Since this is deprecated, this can cause unexpected issues if the library is not updated.

## Proof of Concept

As shown in the docs, the `gogo/protobuf` library is deprecated and is now unmaintained. The newer versions of cosmos expect the `cosmos/gogoproto` library which is active and has implemented a lot of changes. If these changes are expected in the current comsos sdk versions, then using the deprecated older library can lead to unexpected outcomes.

## Tools Used

Manual Review

## Recommended Mitigation Steps

Migrate from `gogo/protobuf` to `cosmos/gogoproto` as mentioned in the docs.



## Assessed type

Library
Canto-main v8 upgrade discards the "IBC transfers" module parameters
Audit: 2024-05-canto-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/app/app.go#L1446-L1480


# Vulnerability details

Before the v8 upgrade, the canto-main application loads each module's parameters so these are re-applied after the
migration:

```go
	case v8.UpgradeName:
		setupLegacyKeyTables(&app.ParamsKeeper)
		storeUpgrades = &storetypes.StoreUpgrades{
			Added: []string{crisistypes.StoreKey, consensusparamtypes.StoreKey},
		}
	}
```

If we look at the implementation of the `setupLegacyKeyTables` function:
```go
func setupLegacyKeyTables(k *paramskeeper.Keeper) {
	for _, subspace := range k.GetSubspaces() {
		subspace := subspace

		var keyTable paramstypes.KeyTable
		switch subspace.Name() {
		case authtypes.ModuleName:
			keyTable = authtypes.ParamKeyTable() //nolint:staticcheck
		case banktypes.ModuleName:
			keyTable = banktypes.ParamKeyTable() //nolint:staticcheck
		case stakingtypes.ModuleName:
			keyTable = stakingtypes.ParamKeyTable() //nolint:staticcheck
		case minttypes.ModuleName:
			keyTable = minttypes.ParamKeyTable() //nolint:staticcheck
		case distrtypes.ModuleName:
			keyTable = distrtypes.ParamKeyTable() //nolint:staticcheck
		case slashingtypes.ModuleName:
			keyTable = slashingtypes.ParamKeyTable() //nolint:staticcheck
		case govtypes.ModuleName:
			keyTable = govv1.ParamKeyTable() //nolint:staticcheck
		case crisistypes.ModuleName:
			keyTable = crisistypes.ParamKeyTable() //nolint:staticcheck
		case evmtypes.ModuleName:
			keyTable = evmtypes.ParamKeyTable() //nolint:staticcheck
		case feemarkettypes.ModuleName:
			keyTable = feemarkettypes.ParamKeyTable() //nolint:staticcheck
		default:
			continue
		}

		if !subspace.HasKeyTable() {
			subspace.WithKeyTable(keyTable)
		}
	}
}
```
... we can notice that the `switch/case` construct misses an entry for the `ibctransfertypes` package, which is however used by the canto-main app.

## Impact
Module parameters applied to the `IBC transfer` module before V8 will be discarded by the V8 migration, which will
initialize the module with its genesis parameters.

## Proof of Concept
- Before migrating to V8, change any parameter of the IBC transfer module
- Migrate to V8
- Check the module parameters

## Tools Used
Code review

## Recommended Mitigation Steps
Consider adding the `ibctransfertypes` package to the `switch/case` construct:

```go
func setupLegacyKeyTables(k *paramskeeper.Keeper) {
	for _, subspace := range k.GetSubspaces() {
		subspace := subspace

		var keyTable paramstypes.KeyTable
		switch subspace.Name() {
		case authtypes.ModuleName:
			keyTable = authtypes.ParamKeyTable() //nolint:staticcheck
		case banktypes.ModuleName:
			keyTable = banktypes.ParamKeyTable() //nolint:staticcheck
		case stakingtypes.ModuleName:
			keyTable = stakingtypes.ParamKeyTable() //nolint:staticcheck
		case minttypes.ModuleName:
			keyTable = minttypes.ParamKeyTable() //nolint:staticcheck
		case distrtypes.ModuleName:
			keyTable = distrty
Govshuttle module does not register it messages to LegacyAminoCodec
Audit: 2024-05-canto-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/x/govshuttle/module.go#L53


# Vulnerability details

The GovShuttle implements the `AppModuleBasic` interface by implementing its methods.

Among these, the `RegisterLegacyAminoCodec` has an incorrect implementation (`canto-main/x/govshuttle/module.go`):

```go
func (AppModuleBasic) RegisterCodec(cdc *codec.LegacyAmino) {
	types.RegisterCodec(cdc)
}

func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
	types.RegisterCodec(cdc)
}
```

In the `(AppModuleBasic) RegisterLegacyAminoCodec` function we can see that the Govshuttle module calls the `types.RegisterCodec(cdc)`
function that does nothing:

```go
func RegisterCodec(cdc *codec.LegacyAmino) {
	// this line is used by starport scaffolding # 2
}
```

This means that the `cdc.RegisterConcrete` calls that other modules make, aren't made for the messages directed to the
Govshuttle module, so these types won't be properly decoded when signed with the LegacyAmino codec.


## Impact
Messages to the Govshuttle module will fail when signed with the legacy Amino method

## Proof of Concept
To prove this issue it is sufficient to send any message signed with the Legacy Amino method to the GovShuttle module

## Tools Used
Code review

## Recommended Mitigation Steps
Consider modifying the `RegisterLegacyAminoCodec` function as follows:
```go
func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    cdc.RegisterConcrete(&types.MsgLendingMarketProposal, "...")
    cdc.RegisterConcrete(&types.MsgTreasuryProposal, "...")
}
```

The `AppModuleBasic` `RegisterCodec` function can also be removed as it has no caller. 


## Assessed type

Other
Govshuttle module does not register the "MsgUpdateParams" on the SDK registry
Audit: 2024-05-canto-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/x/govshuttle/module.go#L58


# Vulnerability details

The Govshuttle `RegisterInterfaces` function registers the protobuf messages handled by the module:
```go
// RegisterInterfaces registers the module's interface types
func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) {
	types.RegisterInterfaces(reg)
}
```

the called function registered all message types, however not `MsgUpdateParams`:

```go
func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
	// this line is used by starport scaffolding # 3
	registry.RegisterImplementations(
		(*sdk.Msg)(nil),
		&LendingMarketProposal{},
		&TreasuryProposal{},
	)

	registry.RegisterImplementations(
		(*govtypes.Content)(nil),
		&LendingMarketProposal{},
		&TreasuryProposal{},
	)

	msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
}
```

We can therefore see that the module's `(a AppModuleBasic) RegisterInterfaces` is incomplete.

## Impact
Because the `govshuttle.MsgUpdateParams` messages aren't registered by the module, proposals containing this action
won't be routed to the Govshuttle module, and will therefore be ineffective.

## Proof of Concept
To reproduce the issue it is sufficient to create and approve a `govshuttle.MsgUpdateParams` proposal.

## Tools Used
Code review

## Recommended Mitigation Steps
Consider modifying the `RegisterInterfaces` function in `canto-main/x/govshuttle/module.go` as follows:

```go
func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) {
	types.RegisterInterfaces(reg)
	reg.RegisterImplementations(
        (*sdk.Msg)(nil),
        &types.MsgUpdateParams{},
    )
}
```

Alternatively, the extra call can be added within the `types.RegisterInterfaces(reg)` function.  


## Assessed type

Other