👀 LooksRare Part 2

Hey everyone welcome back to waints blog. Today I’m going to do a write up on LooksRare Strategy smart contracts.

Disclaimer: I’ve been told by readers that I sometimes have spelling mistakes and poor grammar - I’m not going to fix, that time will be spent reading more code.

Strategies

What are Strategies?

In LooksRares contract structure, a strategy is essentially a way to trade over the platform. For instance, you can sell an NFT via private sale, or bid on a collection of NFTs, or you can perform a standard trade for a fixed price. Before we jump into the strategies, we need to discuss the Execution Strategy interface.

IExecutionStrategy.sol

(IExecutionStrategy.sol)

This interface is heavily dependent on the custom OrderTypes library located at OrderTypes.sol. This library contains two structs (MakerOrder, TakerOrder) and a hash function. LooksRare’s exchange protocol is hybrid off/on chain - meaning, it incorporates off-chain signatures (Maker Orders) and on-chain orders (Taker Orders). The specifics of this are not necessary at the moment, just know that this is how they perform NFT transactions and the hash function is there to provide verifiability. To learn more, visit the docs.

Now that we know what order types are, we can easily walk through the ExecutionStrategy interface. This interface has the following functions:

  • canExecuteTakerAsk - validates a takerAsk against a makerBid and returns a boolean and two ints.

  • canExecuteTakerBid - validates a takerBid against a makerAsk and returns a boolean and two ints.

  • viewProtocolFee - returns an int.

So we have two functions to validate trades and a function to see how much the protocol fee is. This means we should probably see some form of these functions in the strategy contract. Now we can jump into StrategyStandardSaleForFixedPrice.sol.

StrategyStandardSaleForFixedPrice.sol

(StrategyStandardSaleForFixedPrice.sol)

As expected, we have the three functions above implemented in this contract. The only other notable is the constructor, this takes integer protocolFee as input and sets it to the public immutable variable PROTOCOL*_*FEE.

Constructor
Constructor

Next up the two execution functions. these functions are really simple, they take TakerOrder and MakerOrder type structs as input and return a bool and two ints. Realistically its just object comparison wrapped in a function that also returns what token is being traded and at what price. See below:

TakerAsk
TakerAsk

Starting on line 40 we have the beginning of the boolean statement. In plain english this is:

For the makerBid and takerAsk, if the price and tokenID (NFT) are equal, and the makeBid is still in an active timeframe, validate the order as true, if any of these are inconsistent, its false.

Then also throw in the tokenId and number of tokens that are being traded. Next up is the TakerBid function which has almost the same logic.

TakerBid
TakerBid

Pretty much identical.

Final function: viewProtocolFee which returns the protocol fee that was set in the constructor.

viewProtocolFee
viewProtocolFee

Easiest one is out of the way, shall we continue? The next two, we’ll cover together.

StrategyPrivateSale.sol & StrategyAnyItemFromCollectionForFixedPrice.sol

(StrategyPrivateSale.sol & StrategyAnyItemFromCollectionForFixedPrice.sol)

I’m covering these two in the same section because they have the same exact structure as the standard sale one outlined above. The only difference for these is that in the private sale strategy, the canExecuteTakerAsk function always returns false, 0, 0 while in the collection based strategy, the canExecuteTakerBid always returns false, 0, 0 Additionally, the private sale strategy verifies that the targetAddress of the transaction is also the address where the takerAsk originated - hence, private sale.

In the private sale strategy, a taker accepts an offer from the maker to buy an NFT, whereas in the collection based strategy, the taker accepts an offer from the maker to sell the NFT.

The maker / taker system is an efficient way to have a hybrid bid/ask system and pack all strategies into a single interface.

Now we got all the strategies down, its time to continue with the LooksRare core architecture before jumping into the exchange contract. Next up: CurrencyManager.sol