Another fun puzzle - how could you call buy() so that the price is less than 100?
The original version of this question (L16/17 swapped) is quite trivial - the sender can just check isSold to determine what value to return. This modified version requires a bit more trickery 😏.
I'll post my solution tomorrow, curious to see what you all come up with.
Ok, it looks like several of you came up with the same solution I did.
You can use the cost of SLOAD as a flag to determine whether or not a value has been read already. If the cost to SLOAD is 2100+ then you know it's a cold read, otherwise it's a warm read.
gasleft() also works, but it's more annoying to figure out the threshold to use to determine what value to return.
The first thing to note is that this is a proxy contract. If you're not familiar with that term, it means the logic for this contract can be updated in the future without requiring a redeploy. The "proxy" address is permanent, but the implementation contract can be changed.
Today, I decided to do a deep-dive into the age-old gas saving trick:
Using ++i instead of i++.
You may have seen this trick and asked yourself how a change this trivial and inconsequential could result in a difference in gas usage.
Well folks, here's the full explanation 🧵:
Historically, when people have asked me to explain this phenomenon, I've said something along the lines of "well i++ needs to save the original value".
But this was too much of a hand-wavey, wishy-wishy, bullshit explanation for me. I needed to know EXACTLY why this happens.
To solve this mystery, I setup two contracts in Remix: one that would increment a storage variable using i++ and one that would use ++i.
I compiled both contracts with 0.8.17 and optimizer on (the unoptimized code was 🤮).
If you have a mapping(uint256 => bool), you can use a bitmap to drastically reduce gas usage.
In the code below, the bitmap can lead to a ~95% reduction in write costs compared to the mapping.
More info below 👇
A boolean in solidity takes up 1 byte, or 8 bits of storage space. However, a boolean can really just be represented as 1 bit. 0 for false, 1 for true. So how can we utilize single bit storage?
We can use a bitmap.
A bitmap is a mapping of uint256 to uint256. However, each value stored in this mapping contains 256 boolean values, 1 for each bit. When you set a bitmap value, you're actually setting an individual bit. Likewise for reading values, a single bit will be read.
The first set of Starbucks NFTs (Odyssey) have been deployed and minted. These NFTs are earned by completing a set of challenges (trivia, purchases, etc).
The most recent sale for these NFTs was $240.
Here are a couple of technical insights into the project:
It uses the default Nifty Gateway contracts with no extra functionality built in. Just the standard ERC721 functions.
Right now the supply of this collection is 5000. This number can increase in the future because the collection status has not yet been "finalized". You can get this info from the collectionStatus struct.
The @KPRVERSE team came to me recently to help them migrate their smart contract to one with marketplace filtering built-in.
We completed the migration in under an hour with 0 hiccups.
Here's how it was done 🧵:
For context, the KPR community asked the team to block certain marketplaces to prevent wash trading which was affecting floor prices. I personally was not involved in this decision.
I was, however, interested in creating a seamless way for projects to migrate contracts.
Curious how the @valhalla re-roll mechanism works?
Here's a simple breakdown of how the Valhalla team was able to build a fair on-chain re-roll system which allows holders to change their NFTs' appearances🧵:
Each Valhalla NFT has "DNA". This DNA is a 128-bit integer that encodes the metadata for each token. Different segments of the bits represent different trait values for your NFT. There are also 3 bits that are used to denote whether a trait has been re-rolled or "boosted".