Skip to content

Commit

Permalink
Merge pull request #57 from ProjectOpenSea/generateOrder-abi-invalid-…
Browse files Browse the repository at this point in the history
…encoding

changed the checks for `generateOrder`'s return data ABI encoding
  • Loading branch information
0age authored Mar 5, 2024
2 parents fbb182b + c0ee050 commit be2140a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 24 deletions.
60 changes: 37 additions & 23 deletions src/core/lib/ConsiderationDecoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ import {
CriteriaResolver_criteriaProof_offset,
CriteriaResolver_fixed_segment_0,
CriteriaResolver_head_size,
FourWords,
ThreeWords,
FreeMemoryPointerSlot,
Fulfillment_considerationComponents_offset,
Fulfillment_head_size,
FulfillmentComponent_mem_tail_size_shift,
FulfillmentComponent_mem_tail_size,
generateOrder_maximum_returndatasize,
generateOrder_maximum_returned_array_length,
OfferItem_size_with_head_pointer,
OfferItem_size,
OneWord,
Expand Down Expand Up @@ -886,9 +886,13 @@ contract ConsiderationDecoder {
)
{
assembly {
// Check that returndatasize is at least four words: offerOffset,
// considerationOffset, offerLength, & considerationLength
invalidEncoding := lt(returndatasize(), FourWords)
// Check that returndatasize is at least three words:
// 1. offerOffset
// 2. considerationOffset
// 3. offerLength & considerationLength might occupy just one word
// if offerOffset & considerationOffset would point to the same offset
// and the arrays have length 0.
invalidEncoding := lt(returndatasize(), ThreeWords)

let offsetOffer
let offsetConsideration
Expand All @@ -903,10 +907,17 @@ contract ConsiderationDecoder {
offsetOffer := mload(0)
offsetConsideration := mload(OneWord)

// If valid length, check that offsets are within returndata.
let invalidOfferOffset := gt(offsetOffer, returndatasize())
// If valid length, check that offsets word boundaries are within returndata.
let invalidOfferOffset :=
gt(
add(offsetOffer, OneWord),
returndatasize()
)
let invalidConsiderationOffset :=
gt(offsetConsideration, returndatasize())
gt(
add(offsetConsideration, OneWord),
returndatasize()
)

// Only proceed if length (and thus encoding) is valid so far.
invalidEncoding :=
Expand All @@ -921,28 +932,31 @@ contract ConsiderationDecoder {
considerationLength := mload(OneWord)

{
// Calculate total size of offer & consideration arrays.
let totalOfferSize :=
shl(SpentItem_size_shift, offerLength)
let totalConsiderationSize :=
mul(ReceivedItem_size, considerationLength)

// Add 4 words to total size to cover the offset and
// length fields of the two arrays.
let totalSize :=
// Calculate end offsets of offer & consideration arrays.
let offerEndOffset :=
add(
FourWords,
add(totalOfferSize, totalConsiderationSize)
add(offsetOffer, OneWord),
shl(SpentItem_size_shift, offerLength)
)
// Don't continue if returndatasize exceeds 65535 bytes
// or is greater than the calculated size.
let considerationEndOffset :=
add(
add(offsetConsideration, OneWord),
mul(ReceivedItem_size, considerationLength)
)

// Don't continue if either offer or consideration
// length exceeds 65535 or if returndatasize is less
// than the end offsets.
invalidEncoding :=
or(
gt(
or(offerLength, considerationLength),
generateOrder_maximum_returndatasize
generateOrder_maximum_returned_array_length
),
gt(totalSize, returndatasize())
or(
lt(returndatasize(), offerEndOffset),
lt(returndatasize(), considerationEndOffset)
)
)

// Set first word of scratch space to 0 so length of
Expand Down
2 changes: 1 addition & 1 deletion src/types/lib/ConsiderationConstants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ uint256 constant generateOrder_minimumReceived_head_offset = 0x20;
uint256 constant generateOrder_maximumSpent_head_offset = 0x40;
uint256 constant generateOrder_context_head_offset = 0x60;
uint256 constant generateOrder_base_tail_offset = 0x80;
uint256 constant generateOrder_maximum_returndatasize = 0xffff;
uint256 constant generateOrder_maximum_returned_array_length = 0xffff;

uint256 constant ratifyOrder_selector = 0xf4dd92ce;
uint256 constant ratifyOrder_selector_offset = 0x1c;
Expand Down

0 comments on commit be2140a

Please sign in to comment.