The trap of using encodePacked in solidity

I recently came across this mapping in a smart contract which uses hashed encodePacked strings as a key to a mapping.

mapping(bytes32 => uint) private roleIndex;

The key of the mapping is defined as
keccak256(abi.encodePacked(a, b));

while both a and b are strings. This is a typical example of what not to do while using encodePacked - not to use more than 1 dynamic input because encodePacked does not record the length of dynamic input thus it is very easy to generate same results from different inputs. In this particular case since we are hashing it, we will have a problem with hash collision. for example
a = "a", b="bc"
will produce exactly same hash compared to
a="ab", b="c"
which both are 0xe7b823c67cc695498115810929df9ec368d9fb26d1a98a06bac95c33b4858b4f

So basically when using encodePacked, the length of the dynamic input value is not recorded, in this case both inputs end up being “abc”, making this whole mapping completely unusable.

further reading


This was an excellent share. Thank you.