OrderBook

First Flight #43
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: high
Likelihood: low
Invalid

[M-1] Use of `abi.encodePacked()` instead of `abi.encode()` in `getOrderDetailsString` function in the `OrderBook` contract can lead to String Collisions

Description:
The getOrderDetailsString function in the OrderBook contract is responsible for returning a human-readable string representation of an order's details. In its current implementation, this function uses abi.encodePacked() to concatenate and encode various order fields into a single string. While abi.encodePacked() is a convenient way to tightly pack multiple values together, it is not collision-resistant when used for string concatenation. Specifically, abi.encodePacked() performs tight packing of the input data, which means that different combinations of input values can produce the same output bytes if their boundaries are not clearly defined. This can result in collisions, where two distinct sets of order details are encoded into identical byte sequences, potentially leading to incorrect order information being returned to users or external systems that rely on this function.

This issue is particularly problematic in contexts where the string representation is used for display, logging, or off-chain processing, as it undermines the integrity and uniqueness of order data. In the worst case, a malicious actor could craft order details that intentionally collide with another order's string representation, causing confusion or misrepresentation in the order book interface or in downstream integrations.

Impact:
If two different sets of order details produce the same packed encoding, it could result in incorrect or ambiguous information being displayed to users, dApps, or off-chain services that consume the output of getOrderDetailsString. This spoils the integrity and reliability of the order book, as users may be misled about the true state or contents of an order. In addition, this vulnerability could be exploited in edge cases to deliberately misrepresent order data, potentially enabling phishing, spoofing, or other forms of manipulation within the protocol or its ecosystem. Over time, such issues can erode user trust and make it more difficult to audit or verify the correctness of order data.

Proof of Concept:
Add the following test to TestOrderBook.t.sol to demonstrate the collision:

function test_encodePackedCanCollide() external pure {
assertEq(keccak256(abi.encodePacked("abc", "def")), keccak256(abi.encodePacked("abcdef")));
assert(keccak256(abi.encode("abc", "def")) != keccak256(abi.encode("abcdef")));
}

Recommended Mitigation:
Replace the abi.encodePacked() with abi.encode()

function getOrderDetailsString(
uint256 _orderId
) public view returns (string memory details) {
Order storage order = orders[_orderId];
if (order.seller == address(0)) revert OrderNotFound();
.
.
.
details = string(
- abi.encodePacked(
+ abi.encode(
"Order ID: ",
order.id.toString(),
.
.
.
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Appeal created

akronim26 Submitter
about 1 month ago
yeahchibyke Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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