← All writing

How NFT marketplace works-2: Seaport 1.1

openseanft-marketplacenft

It’s a series about NFT trading exploration. If you want to create your NFT or trade your NFT with your peers or have a marketplace on your social media in the future. you can tryMoonPieror join ourdiscordfor more information.

Seaport, developed by 0age from OpenSea, is a powerful and intricate protocol built with assembly code. Given the complexity of the protocol and the extensive information provided in the official documentation, I was inspired to gain a deeper understanding of the design principles behind Seaport. This led me to write a series about the NFT marketplace for those who, like me, are interested in diving deeper into the protocol.

Background

In May 2022, OpenSea unveiled the Seaport protocol and integrated it into its marketplace, transitioning from Wyvern to Seaport. Some of the key features of Seaport include its gas efficiency, ability to support the transfer of multiple assets, and the ability to make offers at the collection and trait level. You can read the post for more features of Seaport.

How NFT marketplace works-2: Seaport 1.1 image 1

Fig 1. Feature of Seaport.

How Seaport Protocol works

Unlike the Wyvern Protocol, which uses an atomic matching process for orders between sellers and buyers, Seaport utilizes a fulfillment order method to match orders. Sellers or buyers can list an order and the other party only needs to fulfill the requirements specified in the order.

Seaport offers four different methods for fulfilling orders

  1. fulfillOrder / fulfillAdvancedOrder
  2. fulfillBasicOrder
  3. fulfillAvailableOrders / fulfillAvailableAdvancedOrders
  4. matchOrders / matchAdvancedOrders

In this post, we’ll take a closer look at the decentralized asset exchange process using fulfillBasicOrder, which is a gas-optimized method for trading only one NFT in one order.

If you are interested in why exchange crypto asset, please refer to the following article

Productivity, Digital asset, and Asset exchange

1. Order match

The order components signed by the order maker can be split into two parts: info, asset transferred.

struct OrderComponents {

address offerer;

address zone;

OfferItem[] offer;

ConsiderationItem[] consideration;

OrderType orderType;

uint256 startTime;

uint256 endTime;

bytes32 zoneHash;

uint256 salt;

bytes32 conduitKey;

uint256 counter;

}

Info

Similar to other protocols like Wyvern, in Seaport, the order maker must specify the offerer’s address, a salt to prevent duplicate orders, and a counter stored on the blockchain to prevent unintentional matches of stale signed orders.

Seaport also has four unique elements for orders. Since Seaport allows users to package multiple assets in one order, the orderType specifies if the order can be partially fulfilled and if the order is restricted to a specific party or open to anyone.

The zone is another account that can fulfill the order when the order is restricted or cancel the order. Additionally, the zone can validate the order using the zoneHash and user-defined validation rules.

The conduitKey is a bytes32 conduit responsible for transferring the assets in the order. If a conduitKey is not specified, the Seaport contract will act as a proxy for transferring the assets involved in the order.

Asset transferred

In Seaport, the assets being sold by the seller are specified as the “offer” and the payment being made by the buyer is specified as the “consideration.” The offer consists of:

  1. token: address of token
  2. identifierOrCriteria: token ID or merkle proof
  3. startAmount: amount before the order is fulfilled
  4. endAmount: amount after the order is fulfilled

If the startAmount is equal to the endAmount, the order is considered to be at a fixed price. However, if the endAmount is greater than the startAmount, the order is considered to be an auction, as the price is determined by the start/end Amount, start/end Time, and the timestamp at the time the order is fulfilled.

2. Order validation

In fulfillBasicOrder order components signed by order maker is transformed into BasicOrderParameters

struct BasicOrderParameters {

address considerationToken;

uint256 considerationIdentifier;

uint256 considerationAmount;

address payable offerer;

address zone;

address offerToken;

uint256 offerIdentifier;

uint256 offerAmount;

BasicOrderType basicOrderType;

uint256 startTime;

uint256 endTime;

bytes32 zoneHash;

uint256 salt;

bytes32 offererConduitKey;

bytes32 fulfillerConduitKey;

uint256 totalOriginalAdditionalRecipients;

AdditionalRecipient[] additionalRecipients;

bytes signature;

}

The Seaport contract validates the order fulfilled by the order taker using the following steps:

  1. Call value: the call value must be zero if the consideration token is not ETH, and non-zero if it is.
  2. Time: the timestamp of the order fulfillment must be between the startTime and endTime.
  3. Parameters: the offset and orderType must be valid.
  4. Consideration length: the consideration length must not be less than the original consideration.
  5. Zone validation: if the order is restricted, the assets must be validated by the zone.
  6. Signature: the signature must be signed by the offerer.
  7. Status: the order must not have been cancelled or completed.

3. Asset transfer

When using Seaport, there is no need to register a custom proxy before trading an asset for the first time, as is the case with Wyvern. Instead, the assets can be transferred using the Seaport contract or a conduit designated by the order maker.

Example with diagram from Seaport

Let’s take a look at an example of a seller selling BAYC #59 for 100 ETH using Seaport’s conduit with Seaport flowchart. The order maker, in this case the seller, creates the order and specifies the assets being sold and the payment received.

In the offer of the order, the seller specifies the following: ItemType: ERC721, TokenAddress:BAYC, IdentifierOrCriteria: 59, StartAmount and EndAmount as 1 (used in AmountDeriver). The consideration is ItemType: Native, TokenAddress: 0x0, IdentifierOrCriteria: 0x0, StartAmount and EndAmount is 100 ETH (in wei), Recipient would be the seller’s address.

The order also includes details such as the time the order is open (StartTime and EndTime) and the orderType (FullOpen, which means the order cannot be partially fulfilled and can be fulfilled by anyone). The ConduitKey is set as Seaport’s conduit, and there are no restrictions on who can fulfill the order, so the conduitKey, zone and zonehash are set to Seaport’s conduit and Pausablezone.

When all the parameters are set, the seller lists herself as the offerer and signs the order. The buyer then fulfills the order by calling the “FulfillOrder” function of the Seaport contract. Let’s take a look at the process of fulfilling an order in the Seaport contract.

  1. OrderCombiner: This step combines multiple orders if the fulfilled order is a combination of multiple orders, such as with the fulfillAvailableOrder function. The FulfillmentApplier filters and checks the validity of the matched order.
  2. OrderFulfiller: After filtering out the order to be fulfilled, the AmountDeriver derives the amount of the token to be transferred and the CriteriaResolution resolves which token is going to be transferred, taking into account criteria such as merkle proof.
  3. OrderValidator: This step verifies the order using the validation checks outlined earlier, such as ensuring the timestamp is within the start and end time and that the order has not been cancelled or completed.
  4. Executor: The final step transfers the specified token, in this case BAYC #59, to the order fulfiller and the specified payment, in this case 100 ETH, to the seller.

https://medium.com/media/5d039f4431c9e58ba51ba1eb88edcf93/href

More features with Seaport

In Seaport, users have the ability to control how their orders are fulfilled.

1. OrderType

There are four options for OrderType full/partial, open/restricted. If the order is set to “full,” the entire order must be fulfilled by one taker. However, if set to “partial,” the taker can fulfill only a portion of the order. If “restricted” is chosen, the taker can only come from a specific zone. If the orderType is “open,” any taker can fulfill the order.

2. FulfillOrder

There are four fulfill methods: fulfillOrder, fulfillBasicOrder, fulfillAvailableOrders, matchOrders.

  1. fulfillOrder: generalized order fulfillment, arbitrary number of tokens.
  2. fulfillBasicOrder: optimization for fulfilling one ERC721 or ERC1155.
  3. fulfillAvailableOrders: fill a group of orders except those not active, has already been fully filled, has been cancelled.
  4. matchOrders: match an arbitrary number of orders with set of fulfillments, allocating offer to consideration.

3. Zone and Conduit

Zone: If the orderType is set to “restricted,” a zone must be specified. This zone will be able to access and fulfill the order, and has customized validity checks.

Conduit: Conduit is a proxy for the token, and the owner of the conduit can add or remove channels. The owner of the conduit can transfer the token, but should be careful to approve token transfer to the conduit.

Conclusion

Seaport is a powerful, efficient and intricate marketplace protocol. Seaport 1.2 is under developed and we’ll introduce the new version of Seaport after released. If you have any questions, please feel free to leave a comment. I’m excited to hear your thoughts and engage in a discussion with you.