Assessment reports>Initia>Low findings>Move coins are case-insensitive in cosmos
Category: Coding Mistakes

Move coins are case-insensitive in cosmos

Low Severity
Low Impact
Medium Likelihood

Description

When performing operations on Move coins, the metadata address is fetched from the coins denom:

// Extract metadata address from a denom
func MetadataAddressFromDenom(denom string) (vmtypes.AccountAddress, error) {
	if strings.HasPrefix(denom, DenomTraceDenomPrefixMove) {
		addrBz, err := hex.DecodeString(strings.TrimPrefix(denom, DenomTraceDenomPrefixMove))
		if err != nil {
			return vmtypes.AccountAddress{}, err
		}

		return vmtypes.NewAccountAddressFromBytes(addrBz)
	}

	// non move coins are generated from 0x1.
	return NamedObjectAddress(vmtypes.StdAddress, denom), nil
}

The issue is that hex.DecodeString is case-insensitive, so a denom of move/AAAA and move/aaaa will both return the same metadata address. Inside the Move VM, the metadata addresses are always case-insensitive when parsed, but the default cosmos SDK behavior is that they are case-sensitive.

This could cause functions such as Coins.Validate to incorrectly validate the coins, even when there are duplicates:

// Validate checks that the Coins are sorted, have positive amount, with a valid and unique
// denomination (i.e no duplicates). Otherwise, it returns an error.
func (coins Coins) Validate() error {

Impact

Any function relying on the fact that a validated coins should contain no duplicates could have this invariant broken.

Recommendations

A check should be added to ensure that the denom values for Move coins are always lowercase.

Remediation

Zellic © 2024Back to top ↑