Seaport Order Validator
Seaport Order Validator provides a solidity contract which validates orders and order components via RPC static calls. Seaport Order Validator currently supports validation of orders (not advanced orders) and provides minimal validation for criteria based items. This is an ongoing effort. The Seaport Order Validator is deployed at the address 0xF75194740067D6E4000000003b350688DD770000
.
There are a variety of functions which conduct micro and macro validations on various components of the order. Each validation function returns two arrays of uint16s, the first is an array of errors, and the second is an array of warnings. For a quick lookup of issue codes, see the issue table.
Table of Contents
JS Package Usage
- Add the package via
yarn add @opensea/seaport-order-validator
ornpm i @opensea/seaport-order-validator
- Import the package to your JS/TS file via
import { SeaportOrderValidator } from "@opensea/seaport-order-validator"
- Create an instance of
SeaportOrderValidator
const validator = new SeaportOrderValidator(new ethers.providers.JsonRpcProvider(<RPC>));
- All validation functions are exposed to the
SeaportOrderValidator
instance
Macro-Validation
-
There are two macro-validation function,
isValidOrder
andisValidOrderWithConfiguration
.isValidOrder
simply callsisValidOrderWithConfiguration
with a default configuration as follows:{ primaryFeeRecipient = address(0), primaryFeeBips = 0, checkCreatorFee = false, skipStrictValidation = false, shortOrderDuration = 30 minutes, distantOrderExpiration = 26 weeks }
-
isValidOrderWithConfiguration
- Calls the following micro-validations and aggregates the results:
validateTime
- Called with variables from configurationvalidateOrderStatus
validateOfferItems
validateConsiderationItems
isValidZone
validateStrictLogic
- if skipStrictValidation is false. Called with the parameters from the configurationvalidateSignature
- Calls the following micro-validations and aggregates the results:
Micro-Validation
-
validateTime
- Validates the timing of the order- Errors:
- End time must be after start time
- Current time must be before or equal to end time
- Warnings:
- End time is in more than
distantOrderExpiration
(distant expiration) - Start time is greater than current time (order not active)
- Order duration is less than
shortOrderDuration
(either endTime - startTime or endTime - currentTime)
- End time is in more than
- Errors:
-
validateOrderStatus
- Validates the order status from on-chain data- Errors:
- Order is cancelled
- Order is fully filled
- Errors:
-
validateOfferItems
- Validates the offer item parameters and balances/approval- Errors:
- Zero Offer Items
- Warnings:
- More than one offer item
Nested validation call to
validateOfferItem
for eachofferItem
- Errors:
-
validateOfferItem
- Validates the parameters and balances/approvals for one offer item- Nested validation call to
validateOfferItemParameters
and if there are no errors, a subsequent call tovalidateOfferItemApprovalAndBalance
- Nested validation call to
-
validateOfferItemParameters
- Validates the parameters for one offer item- Errors:
- Either the startAmount or the endAmount must be non-zero
- The contract must exist and abide by the interface required for the given
ItemType
. - Identifier must be 0 for fungible tokens
- Token address must be null-address for native offer item
- Amounts must be 1 for if the
ItemType
is an ERC721
- Warnings:
- Large steps for amount. This is due to the fact that as time passes, the change in amount will be relatively drastic at each step. Occurs if min amount is less than 1e15 and
minAmount ≠ maxAmount
. - High velocity for amount. This means that the price changes more than 5% per 30 min relative to the highest amount.
- Large steps for amount. This is due to the fact that as time passes, the change in amount will be relatively drastic at each step. Occurs if min amount is less than 1e15 and
- Errors:
-
validateOfferItemApprovalAndBalance
- Validates the balances/approvals for one offer item- Errors:
- Must be the owner of non-fungible items
- Must have sufficient balance of fungible items
- Must have sufficient allowance to the given conduit (seaport if none given)
- Warnings:
- Native offer item (a native offer item can not be pulled from the user wallet for fulfillment)
There is also a nested validation call to
getApprovalAddress
to get the associated conduit for checking approvals. - Errors:
-
validateConsiderationItems
- Validate the parameters of the consideration items- Warnings:
- Zero consideration items
For each consideration item, there is a nested validation call to
validateConsiderationItem
which is just a wrapper forvalidateConsiderationItemParameters
- Warnings:
-
validateConsiderationItemParameters
- Check the parameters for a single consideration item- Errors:
- Either start amount or end amount must be non-zero
- The recipient can not be the null address
- ERC721 type must have amounts be one
- ERC721 token with identifier must exist
- All token contracts must exist and implement the required interfaces
- Native consideration item contract must be zero
- Identifier for fungible items must be 0
- Errors:
-
isValidZone
- Checks if the zone accepts the order- Errors:
- Zone Rejected Order
- Note: Validation always passes if given zone is an EOA
- Zone caller is msg.sender
- Zone Rejected Order
- Errors:
-
validateStrictLogic
- Validate strict order logicThe first consideration item is called the “primary consideration” for this section.
- Errors:
- Force 1 offer item along with at least one consideration item
- Either the offer item or the primary consideration item must be fungible—the other non-fungible.
- This ensures an either an offer or listing typed order
- If
primaryFeeRecipient
andprimaryFeeBips
are non-zero, the second consideration item must be set correctly to the primary fee consideration. This must be omitted if the primary fee would be zero. - If
checkCreatorFee
is set to true, the creator fee engine is checked for royalties on the non-fungible item. If the creator fee is non-zero, the creator fee consideration item must be the next consideration item in the sequence. - There may be one last consideration item which signifies a private sale. This consideration item must be exactly the same as the offer item and the recipient must not be the offerer (no private sale to self).
- There may not be any additional consideration items.
- Errors:
-
validateSignature
- Validates the signature using current counterCalls
validateSignatureWithCounter
using the offerers current counter -
validateSignatureWithCounter
- Validates the signature using the given counter- Errors:
- Counter below current counter - signature will never be valid
- Signature Invalid
- Warnings:
- Signature Counter High - The signature counter is more than 2 greater than the current counter for the signer.
- When error is invalid, original consideration Items field in order does not match the total consideration items. This may be the cause of the invalid signature.
- Errors:
-
getApprovalAddress
- Gets the approval address for a conduit key- Returns the approval address for the given conduit key. (seaport address if conduit key is 0)
- Errors:
- Conduit key invalid (not created). Returns zero address for the approval address.
Merkle Validation
-
sortMerkleTokens
To generate a merkle root for a criteria order, the included token ids must first be sorted by their keccak256 hash. This function sorts accordingly.
-
getMerkleRoot
- Generates the merkle root from the given
includedTokens
- If
MerkleError
is given, elements are not sorted correctly, or there are too many elements.
- Generates the merkle root from the given
-
getMerkleProof
- Generate the merkle proof for an element within the
includedTokens
at indextargetIndex
.
- Generate the merkle proof for an element within the