TLDR:
Moonbirds belong to the Proof ecosystem. In this post I take a look and break down 3 smart contracts: Moonbirds, Proof pass and Oddities.
Moonbirds Nesting allows for soft-staking without giving up NFT’s ownership.
Proof passes minted with a Dutch Auction while Oddities had a drop mechanic.
These contracts are all elegantly designed and developed, but elegance of the code does not necessarily equate to perceived value as floor price has shown.
Last week’s post on writing your first Smart Contract in 3 minutes was well received! This felt great since my goal is always to educate and inform non-technical people in Web3 and show them that things don’t have to be as complicated as people think. If readers have any other topics they’d like me to cover please let me know at afoxinweb3.
This past week I bought myself a Moonbird NFT for the first time alongside a couple of Oddities. I bought a Moonbird now because their floor price has collapsed down from their peak of over 25 ETH during the bull-run to approximately 2 ETH now, that was their original mint price.
I’m particularly interested in Moonbirds because of their focus on Web3 Art, which is an area we’re focused on too at my company Token Page as we’re building out a product tailored for Web3 Artists right now.
Considering I looked at the Cryptopunks smart contracts a couple weeks ago, I thought this week I would look at the Proof ecosystem’s smart contracts that Moonbirds belong to.
PROOF
A brief history of Proof is that Kevin Rose (KRO), an early Web2 entrepreneur who worked on the precursor to community-driven Internet with his company Digg, released 1000 Proof passes in 2021 that he used to token-gate his Proof Discord and create his own inner circle within Web3.
With the rise of PFPs during the bull-run KRO grew the Proof ecosystem further by releasing 10,000 Moonbirds that gave more people access to the community. Each of these later spawned an Oddity NFT allowing for another 10,000 members in the Discord with this lower tier NFT.
Kevin’s definitely made some missteps and not yet mastered what keeps the Web3 crowd engaged hence the floor price drop from 25+ ETH to 2 ETH. But he has a lot of experience in building tech companies and he’s secured $50M in financial firepower from VCs so the Proof ecosystem is an important one to pay attention to in Web3.
The 3 main contracts for Proof that I’ll cover are:
Moonbirds https://etherscan.io/address/0x23581767a106ae21c074b2276d25e5c3e136a68b#code
Proof Pass https://etherscan.io/address/0x08d7c0242953446436f34b4c78fe9da38c73668d#code
Oddities https://etherscan.io/address/0x1792a96e5668ad7c167ab804a100ce42395ce54d#code
Moonbirds
Moonbirds follow a lot of the standards that were created over the past years - unlike Cryptopunks that I discussed a couple weeks ago who were created before the standards emerged.
Firstly, you can see the contract was compiled with a compiler that neatly breaks it down into its 37 constituent files, with Moonbirds.sol being the most important one. And with around 420 lines Moonbirds.sol has a lot more complexity than the Punks with their 250 odd lines.
Moonbirds are built on top of Azuki’s ERC721A that’s a gas-efficient extension they made to the ERC721 standard I’ve covered before. Plus it even implements the ERC2981, which is a standard aimed to introduce royalty information into sales that honestly most marketplaces just ignore.
There’s a lot of variables and functions to help with the minting of Moonbirds for Proof pass holders first, which is made obvious by the separation of the function mintPROOF() and mintPublic(). Both call the same underlying function handlePurchase() though to do the mint with a standard _safeMint() call.
Nesting
The majority of the rest of the contract outside of the minting focuses on the concept of “nesting”, which is a form of soft-staking. Staking being where you commit to not sell your Moonbird and in turn are rewarded for this.
In a more conventional staking method you would send the NFT to another staking contract that holds it for you. But with soft-staking you don’t have to send it anywhere meaning you still retain ownership of the NFT. Nesting just calls the function toggleNesting() that saves the time nesting kicked off into a variable nestingStarted[tokenId] = block.timestamp;.
Nesting then blocks sales of the NFT by taking advantage of the function _beforeTokenTransfers() that gets called within safeTransferFrom() used for transferring during a sale. It does this with a “require” call that checks nestingStarted[tokenId] has a timestamp saved into it suggesting that the Moonbird is nesting. If it is set to 0 then there’s no timestamp and its not nested so the transfer can go through.
An interesting thing to note is that a better solution would be to block approval of transferring the single nesting Moonbird. However since most NFT marketplaces use the setApproveAll() function to sell NFTs, the code cannot be written in such a way that nesting blocks approval for a single Moonbird since that would mean that nesting even just one would block a holder from selling the rest of his Moonbirds.
Nesting Quirks
Curiously there is a way to transfer a Moonbird without un-nesting, which is through the function safeTransferWhileNesting(), the comment here suggests it was used for Moonbirds during the minting process. But the code simply allows you to send to another address without losing the nesting state as long as you own it.
There’s also a way for Proof admins to “expel” Moonbirds from their nest for “bad behaviour” using expelFromNest(). Bad behaviour could for example be if a holder has put a nested Moonbird up for sale such that it pushes the floor price of the Moonbirds down, knowing that nobody will be able to buy that Moonbird since its nested.
Proof Pass
The Proof pass came before the Moonbirds NFT and is implemented as an ERC721 even though every metadata is the same and could therefore be probably implemented for less gas as an ERC1155.
Otherwise the contract code is predominantly focused on how it was sold via a “LinearDutchAuction”. This is where the NFT is sold at the maximum price first and decreases in price regularly by a constant amount. This means buyers who are happy to pay the higher price get in earlier, while others try to get a lower price but risk there not being any available.
The constructor then defines the variables such that it started at 5 ETH and at every 15 minutes (ie. 900 seconds / 60 seconds per minute) there was a decrease of 0.5 ETH in price up to a maximum of 9 decreases. The constructor also defines a maximum of 1000 items in total with a maximum of 2 items per address per mint and the ability to only transact with the contract 1 time, so buyers had to make up their mind if they minted 1 or 2 from the get-go during the auction. Plus they reserved the right for 75 free NFTs that they gave out to specific people.
This Dutch Auction logic is then entirely handled by LinearDutchAuction.sol and Seller.sol files working hand-in-hand. While the purchase simply runs a standard ERC721 _safeMint() for the number of NFTs the minter wanted to buy.
Oddities
Oddities are a relatively simple ERC721A with only 122 lines of code. Most of the base functionality is inherited from other standard contracts, but where it becomes most interesting is in the drop mechanics.
Oddities were intended as a drop for all nested Moonbird holders while unnested Moonbirds are inelligible for the drop and their Oddities were sent to the project’s treasury address to be distributed as they preferred. Naturally the goal here is to reward only holders who stake and are aligned with the Moonbirds community.
The drop is an elegantly written function that got called just once to mint all 10,000 Oddities. It loops through all Moonbirds checking that the holder’s Moonbird was nested and if so minting the Oddity to their address, otherwise minting it to the treasury. It does this in a really compact way with just a single _mint() call, not even a safeMint() since it knows Moonbird holders have valid addresses and this reduces gas.
Curiously there’s also a simpler drop function called dropTo() that also lives in the code. It would take a list of all individual drop addresses computed off chain and then manually go through and mint all of them 1-by-1 to these recipient addresses. It sat as a backup in the code in case the other call went wrong but never needed to be used.
In-Chain
Proof also more recently created a way for Moonbirds data to be stored forever on-chain, or rather what they call “in-chain”. You can read more about it here but essentially there’s on-chain code that returns the Moonbirds images directly rather than returning a path to the image on IPFS or some other server.
To keep this post from growing any longer though I won’t go into detail about how this contract works but essentially its similar to the Cryptopunks’s data contract I discussed previously and means Moonbirds will live on for as long as Ethereum does!
As a final note, for most users NFTs look essentially all pretty much the same having a picture and some traits, but when comparing the code for Moonbirds with CryptoPunks for example you can see that the Moonbirds are far more complex! Nonetheless, complexity does not define value and each NFT is ultimately only as valuable as users perceive them.