code-423n4 / 2023-03-canto-identity-findings

1 stars 1 forks source link

Implementation error in Namespace.fuse() leads to a wrong unicode representation #275

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-03-canto-identity/blob/077372297fc419ea7688ab62cc3fd4e8f4e24e66/canto-namespace-protocol/src/Namespace.sol#L144 https://github.com/code-423n4/2023-03-canto-identity/blob/077372297fc419ea7688ab62cc3fd4e8f4e24e66/canto-namespace-protocol/src/Utils.sol#L73

Vulnerability details

Impact

The font class of a tile will be always considered as 0 (emoji) when a user registers a name.

Proof of Concept

To register a name, fuse() is used taking as input the data of the characters.
The name to register is a string created by converting the characters data to bytes with Utils.characterToUnicodeBytes taking as input the tile data (font class, characterIndex...) but the font class argument passed to the function is always 0. The problem is that the Unicode representation will be wrong as it always considers the character as an emoji.

https://github.com/code-423n4/2023-03-canto-identity/blob/077372297fc419ea7688ab62cc3fd4e8f4e24e66/canto-namespace-protocol/src/Namespace.sol#L144

bytes memory charAsBytes = Utils.characterToUnicodeBytes(0, tileData.characterIndex, characterModifier);

https://github.com/code-423n4/2023-03-canto-identity/blob/077372297fc419ea7688ab62cc3fd4e8f4e24e66/canto-namespace-protocol/src/Utils.sol#L73

/// @notice Convert a given font class, character index, and a seed (for font classes with randomness) to their Unicode representation as bytes
    /// @param _fontClass The class to convert
    /// @param _characterIndex Index within the class
    /// @param _characterModifier Some characters have numeric modifiers (skin tone modifier for emojis, seed generated at minting for zalgo)
    function characterToUnicodeBytes(
        uint8 _fontClass,
        uint16 _characterIndex,
        uint256 _characterModifier
    ) internal pure returns (bytes memory) {

For example a user wants to register a name with a tile with data: fontClass = 1 characterIndex = 5 uint8 characterModifier = 0

Then the user wants to register another name using as tile data: fontClass = 5 characterIndex = 5 uint8 characterModifier = 0

The second transaction will produce the same name and will fail

uint256 currentRegisteredID = nameToToken[nameToRegister];
if (currentRegisteredID != 0) revert NameAlreadyRegistered(currentRegisteredID);

Tools Used

Manual review

Recommended Mitigation Steps

Use tileData.fontClass instead of 0.

c4-judge commented 1 year ago

0xleastwood marked the issue as duplicate of #117

c4-judge commented 1 year ago

0xleastwood marked the issue as satisfactory

c4-judge commented 1 year ago

0xleastwood changed the severity to 3 (High Risk)