Solidity

abi.encodePacked

abi.encodePacked is a Solidity encoding function that tightly packs values without the padding, offsets, and dynamic-length delimiters used by abi.encode.

It creates shorter bytes, but different inputs can produce the same packed bytes when dynamic values are mixed.

abi.encodePacked Explained in Detail

abi.encodePacked encodes values in a compact packed format. It is useful in some low-level contexts, but it can be unsafe when hashing multiple dynamic values because boundaries are not always preserved.

Two different input sets can produce the same packed bytes.

Smart contract example

The two hashes below can collide when dynamic values are rearranged:

keccak256(abi.encodePacked("ab", "c"));
keccak256(abi.encodePacked("a", "bc"));

Both encode to the same bytes before hashing.

abi.encodePacked in Auditing

Packed encoding bugs often affect signatures, commitments, permits, merkle leaves, authorization digests, and commit-reveal schemes. They can become signature replay or access-control bugs when the hash authorizes value movement.

Red flags in code

  • keccak256(abi.encodePacked(...)) with two or more dynamic fields.

  • Packed hashes used for signatures or authorization.

  • Strings, bytes, arrays, or user-controlled dynamic values mixed together.

  • No domain separator, nonce, chain ID, or verifying contract in signed data.

  • Custom digest code instead of standard EIP-712.

How to test or review it

  • Prefer abi.encode when hashing structured data.

  • If packed encoding is required, ensure at most one dynamic field is used, or use fixed-length fields, explicit length-prefixing, or canonical escaping.

  • Reproduce hashes with the Keccak-256 tool.

  • Test collision-shaped inputs such as ("ab", "c") and ("a", "bc").

  • Review every packed hash that controls funds, permissions, or eligibility.

Sources