# Incorrect Encoding of Order Hashes

Seaport's _encodeOrderHashes advanced the memory pointer past the array, copying unallocated memory into ratify/validate order payloads, corrupting order hashes.

- Payout: Audit contest
- Severity: medium
- Program: OpenSea
- Found by: 0xsomeone
- Disclosed: 2023-03-21
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2023-01-opensea#m-01
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-opensea%3AM-01
- Tags: area:web3 domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:memory-corruption

**Target:** ConsiderationEncoder.sol _encodeOrderHashes / MemoryPointerLib::copy (0x04 precompile)
**Root cause:** In _encodeOrderHashes, `srcLength.next().offset(headAndTailSize)` moves the pointer past the array's last element instead of to the array data start, so the 0x04 identity precompile copies from unallocated memory. An empty orderHashes array (headAndTailSize 0) also makes copy fail with returndatasize 0.
**Steps:**
1. Locate `_encodeOrderHashes` in contracts/lib/ConsiderationEncoder.sol#L569-L574.
2. Observe the source pointer computed as `srcLength.next().offset(headAndTailSize)`: `next()` skips the length word, `offset(headAndTailSize)` jumps past the last element.
3. Pass that pointer to `MemoryPointerLib::copy`, which invokes the 0x04 precompile to copy the region.
4. The precompile reads unallocated memory, so incorrect bytes are written as order hashes into the payload built by `_encodeRatifyOrder` / `_encodeValidateOrder`.
5. With an empty orderHashes array, headAndTailSize is 0 and copy fails because the precompile returns returndatasize 0.
**How found:** Manual code review of the encoder combined with reading ETH precompile (0x04 identity) and Solidity compiler documentation to reason about memory pointer arithmetic and what region the copy would actually read.
**Exploitation:** Not a direct theft path; downstream functions such as _assertRestrictedAdvancedOrderValidity consume the malformed payload, so zones and contract offerers cannot rely on the orderHashes array and validation/ratification misbehaves.
**Insight:** When auditing assembly memory-pointer helpers, trace each `.next()`/`.offset()` against the actual ABI head/tail layout: an offset applied after skipping the length word lands past the array, and identity-precompile copies from such pointers silently read unallocated memory rather than reverting.

