Skip to content

GetAuthorityMetadata doesn't check nil store bytes before Unmarshal #294

@giwaov

Description

@giwaov

Bug Description

In the tokenfactory module, GetAuthorityMetadata doesn't check whether the value bytes retrieved from the store are nil before passing them to proto.Unmarshal. If the key exists but has nil/empty value (which can happen during certain state transitions), proto.Unmarshal will silently return an empty struct instead of an error, potentially masking state corruption.

File: x/tokenfactory/keeper/admins.go

func (k Keeper) GetAuthorityMetadata(ctx sdk.Context, denom string) (types.DenomAuthorityMetadata, error) {
    bz := store.Get([]byte(denom))
    // no nil check on bz here!
    
    var metadata types.DenomAuthorityMetadata
    err := proto.Unmarshal(bz, &metadata)
    // ...
}

There are 13+ callers of this function throughout the codebase (in msg_server.go, keeper.go, grpc_query.go, etc.) and they all check the returned error — but if nil bytes are passed to Unmarshal, it won't error, it'll just give back a zero-valued metadata struct. This could lead to unexpected behavior where a denom appears to have no admin when really the data is just missing/corrupt.

Steps to Reproduce

  1. Have a situation where a denom key exists in the authority store but has nil/empty bytes
  2. Call GetAuthorityMetadata for that denom
  3. proto.Unmarshal(nil, &metadata) succeeds silently and returns an empty metadata
  4. The caller proceeds as if the denom has no admin, when the real issue was data corruption

This matters because tokenfactory admin operations (mint, burn, change admin) rely on this function to auth-check the caller.

Expected Behavior

Check for nil bytes before unmarshaling:

bz := store.Get([]byte(denom))
if bz == nil {
    return types.DenomAuthorityMetadata{}, types.ErrDenomDoesNotExist.Wrapf("denom %s", denom)
}

Actual Behavior

Nil bytes are silently unmarshaled into an empty metadata struct, masking potential state corruption.

Impact

Medium - Could lead to incorrect authorization checks in the tokenfactory if the store state is corrupted. The empty metadata would have an empty Admin field, potentially allowing operations that should be restricted or blocking operations that should be allowed, depending on how the caller checks admin status.

Fix is available in PR #288.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions