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.
/// @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);
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
https://github.com/code-423n4/2023-03-canto-identity/blob/077372297fc419ea7688ab62cc3fd4e8f4e24e66/canto-namespace-protocol/src/Utils.sol#L73
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
Tools Used
Manual review
Recommended Mitigation Steps
Use tileData.fontClass instead of 0.