Pricing NFTs On-chain
The Pawnbroker’s dilemma
Let’s say you run a pawn shop. Your job looks something like this:
- Someone brings you an item.
- You assess it and assign it a dollar amount.
- You loan out this amount to the customer and hold on to the item as collateral.
- Later, the customer gives you the money back along with interest and you return the item.
Your goal here is to earn as much interest as possible. To accomplish this, you want to offer loans at a value and interest rate which maximizes the number of people who want to do business with you. Notice that the higher interest rate you charge, the less likely someone is to lend their item to you.
You also would only like to pawn items which the owner is likely to want to take back, else in the worst case (When everyone just takes your money and leaves), you become a glorified second-hand store and you will have to deal with potentially illiquid inventory.
The NFT pawn shop
I have been working on Hawk protocol, which is simply an onchain version of the above problem. Instead of real world collectibles, the protocol allows you to collateralize your NFT’s and get SOL in return.
Existing solutions
There are projects which solve this problem, but most of them create a 2 sided marketplace where one person quotes a value they are willing to borrow for and the other person can choose to lend to them. This is slow and takes a lot of back and forth, since the orderbooks in these markets are slim.
Also, NFTs are illiquid and there are not many financial projects/protocols you can use them in, so a lender will always lend you significantly less than what an algorithmically fair lender can give you.
In Hawk protocol, there is no centralized pawn broker, and SOL is lent out and borrowed from a decentralized liquidity pool which anyone can add SOL into.
This post is just a log of my thought process on how I went about designing such a protocol.
Assessing an NFT
NFTs are usually part of a collection, which can be thought of as card packs. Some NFTs in the collection are more “rare” than others due to special traits.
There is no true “value” to the NFT other than what collectors are willing to pay for it. Thus, the most accurate “model” for finding the price can only incorporate past trade data. There is no other factor (which can be made easily available on-chain) which can help predict price better.
For any given NFT, assume we have access to the floor price (the value of the cheapest NFT from its collection) and a list of past trades. Given just this data, we need to determine a “fair price” to lend out algorithmically.
Initial loan amount
Note that the floor price for any collection is based on past data and not on some inherent value primitive tied to the NFT.
Thus, lending out any amount significantly greater (lets say >= 200%) than the floor price doesn’t make any sense, if you want to make money in the long run.
The simplest way to do this would be to lend out a fixed fraction
e.g. 80%
of the floor price of the NFT collection and add multipliers for each source of “rarity”, up to some max multiplier e.g. 200%
of the floor price.
I tried out a variety of pricing mechanisms, and this one seems to be the easiest to reason about. Being simple, it also has the added advantage of being easier to program defensively against pricing/oracle attacks.
Interest Rates
In the “real” world, most pawnbrokers have predetermined interest rate terms, based on the item, their personal risk tolerance and regulations.
On the blockchain however, we set interest rate based on pure supply and demand, similar to Compound:
$$U = (Borrows)/(Cash + Borrows)$$ $$Rate_{borrow} = x + U * y$$ $$Rate_{supply} = U * Rate_{borrow}$$
Borrows
is the current market value of NFTs collateralized, Cash
is amount of liquidity left in the pool, and x
and y
are constants < 1
. Setting these is more of an art than a science and values of x = 1 to 5%
and y = 20 to 50%
make sense.
These formulas ensure that the rate of supply decreases when there is too much cash and incentivize borrowers to borrow more, and vice versa.
Liquidations.
Liquidations are significantly more complicated than in a simple lending DeFi protocol. Liquidations happen when the floor price of a NFT collection drops significantly in relation to the amount that has been lent out.
For v1 of this protocol, the onchain program simply takes ownership of the NFT if the floor price has dropped >50%
. I am looking into better ways of handling this, including fractionalization.
DAO
Whenever you write an on-chain program, you need to think in terms of a red team mindset. How would you exploit this protocol?
The simplest way to do this would be to mint a NFT collection, perform a bunch of wash trades to make it seem as if the NFT’s are valuable, then collateralize them all and run away with the money.
There is no way to detect/prevent this on-chain. A DAO can help manage such risks by voting on which NFT collections are allowed to be collateralized. Only after a significant portion of the community believes that a NFT collection is valuable, it can be used as collateral in the protocol.
The DAO can also help manage borrowing ratios/multipliers per collection and mitigate some other risks.
Conclusion
This problem looks simple, however there are quite a few subtle details which have been interesting to work through.
Update 30 Oct 2021
The winners of Solana Ignition hackathon are announced here. Although Hawk protocol didn’t win, it received an honorable mention. Congrats to all the winners!
I will continue to work on Hawk and hopefully launch it soon on mainnet. See you then!