40,000 USDC
View results
Submission Details
Severity: gas

`abi.encode()` is less efficient than `abi.encodePacked()`

Summary

abi.encode() is less efficient than abi.encodePacked()

Vulnerability Details

abi.encode will apply ABI encoding rules. Therefore all elementary types are padded to 32 bytes and dynamic arrays include their length. Therefore it is possible to also decode this data again (with abi.decode) when the type are known.

abi.encodePacked will only use the only use the minimal required memory to encode the data. E.g. an address will only use 20 bytes and for dynamic arrays only the elements will be stored without length. For more info see the Solidity docs for packed mode.

For the input of the keccak method it is important that you can ensure that the resulting bytes of the encoding are unique. So if you always encode the same types and arrays always have the same length then there is no problem. But if you switch the parameters that you encode or encode multiple dynamic arrays you might have conflicts.
For example:
abi.encodePacked(address(0x0000000000000000000000000000000000000001), uint(0)) encodes to the same as abi.encodePacked(uint(0x0000000000000000000000000000000000000001000000000000000000000000), address(0))
and abi.encodePacked(uint[](1,2), uint[](3)) encodes to the same as abi.encodePacked(uint[](1), uint[](2,3))
Therefore these examples will also generate the same hashes even so they are different inputs.
On the other hand you require less memory and therefore in most cases abi.encodePacked uses less gas than abi.encode.

Impact

There is 1 instance of this issue:

File: 2023-07-escrow/src/EscrowFactory.sol

77: byteCode, abi.encode(price, tokenContract, buyer, seller, arbiter, arbiterFee)

Tools Used

Manual code review.

Recommendations

Use abi.encodePacked() where possible to save gas

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.