By now everyone has heard of CryptoKitties, a cute game that went viral to the point of overloading the whole Ethereum network. This is the inside story behind how we made $107K investing in CryptoKitties and briefly set the record for the largest sale ever (currently second-largest). Later, we made ~$8K running an automated arbitrage bot. While playing the speculation game at the height of the mania was exciting, the bot was fairly technically involved and will be interesting to people who want to learn blockchain engineering in general.
As I was toying with my Ethereum smart contracts on a regular Saturday night (December 2), something was clearly off: transactions were stuck and took much longer than usual to confirm. A quick investigation showed there were 10–20 times more pending transactions than usual, and many of them were going to the same mysterious address, 0x06012..66d. This is how I first learned of the now-famous CryptoKitties game.
Next morning I called Oleg Ostroumov, a close buddy who runs a top crypto hedge fund in Russia to discuss this unusual phenomenon. While the CryptoKitties game was merely a curiosity for me, Oleg immediately spotted a lucrative investment opportunity. First, we were clearly among the earlier entrants. Second, the game looked like it had all the precursors of going viral, similar to Pokemon Go, and was in the early stage of a hockey stick explosion.
Now the question was, which Kitties should we buy? The marketplace offered 4 ways to sort Kitties: cheapest first, most expensive first, newest first, oldest first (note: the website had been redesigned since). The first 3 options are clearly transient: you can always put a cheaper, more expensive, or a newer Kitty on the market. Oldest, however, is like diamonds: forever. Thus we decided to buy single-digit Founder Cats, despite their already hefty price tags: somebody just snatched them at
25 ETH and re-listed the lineup at
50 ETH (
$25K), with Founder Cat #1 trading even higher at
Oleg bought Founder Cats #4, #6, #8 at
50 ETH each (
$25K at the time), and I put up
$5K for a 20% equity stake in Founder Cat #4. We were pretty optimistic about the mania and re-listed the Kitties at
250 ETH, 5x the purchase price.
As a side-note, we wasted about an hour because of posting a low gasPrice, and had to reinstall MetaMask (at the time it did not have the “resend transaction with increased gasPrice” feature — it was added right after). Lesson learned: if you’re making a
$25K purchase, do not try to save
$20 on fees.
Right after hanging up on the call I considered the chances that this was going to be my personal record yet for the most ridiculous way to waste
$5K. Probably pretty high.
The subtle art of exiting the top
Over the next days (December 2–5), the game entered the viral explosion phase. Given the addictiveness, it was pretty hard to focus on anything else. Clearly, the craze was not going to last: the game mechanics were way simpler than say Pokemon Go, with just two functions available, either buy or breed them to produce new ones. We assumed it could last for a couple weeks tops, so it was important to formulate a rational exit strategy in advance and stick to it.
We used three metrics. First, Google Trends for “CryptoKitties” showed how frequently people Googled information about the game, which is a pretty good leading indicator of interest. Second, GasGuzzlers shows the top gas-consuming smart contracts on the network and the share of gas they consume (for CryptoKitties it was ~4% when we entered and ~20% at peak popularity). Third, we watched the market conditions and the prices of recent sales on a very nicely built app, https://kittysales.herokuapp.com/.
On December 4–5, several less prestigious Kitties (#35, #78, #87) sold for almost
200 ETH, so we were confident our listing price was well-adjusted. However, December 5–6 was the top on every metric, and by the end of December 6 the popularity was clearly trending downhill. Observing this, we had an emergency call on December 6 trying to figure out what to do with the Kitties, none of which sold at our listed
250 ETH price yet. I wanted to re-list the Kitty at a lower price of
100 ETH, whereas Oleg was steadfast on sticking to
250 ETH. Given our disagreement about the value of the Kitty, we did the obvious arbitrage: I sold my 20% stake to him at a
100 ETH “Kitty valuation”, essentially doubling my money on the spot. Little did I know I’d only be happy about this deal for about 20 minutes…
I kept watching the marketplace out of curiosity. Now, 20 minutes after Oleg bought me out, I saw our Founder Cat #4 sold at the original
250 ETH price. I was so confident it was Oleg generating game activity for his merchandise, I barely bothered to ask him. When I did, however, I learned the full power of HODLing: it was a genuine purchase, we had no idea who was the buyer, and he’d just set the world record for selling a collectible on the blockchain.
Having had such a lucky start to the game, we discussed what else we could do with it. Peak hype was clearly over and ridiculous prices for the rarest Kitties were unattainable, but the long tail remained: people still wanted to play, and to get some kind of Kitty for themselves.
So we decided to try running an automatic arbitrage bot on the long tail of cheaper Kitties. Like any reseller strategy, it essentially consisted of the following three steps:
- Determine clusters of Kitties that should be priced roughly the same. The parameters we looked at were Rarity, Cooldown and Generation (only Gen 0 and Gen 1 were expensive enough to bother). Kitties with same values across these 3 parameters were deemed equivalent (ignoring cuter artwork or Cattribute variations).
- Buy underpriced items within each class. In our case, we only bought the cheapest Kitty across every parameter set.
- Resell the acquired item for more. In our case, we wanted to avoid a race to the bottom with other potential resellers, so we listed each Kitty at slightly below the second-cheapest price (similar to Google’s second-price auction).
After exploring several blockchain libraries, we found refactoring my previous Bancor front-running code to work best. The strategy was: watch for transactions that put Kitties on sale, buy out immediately if it matches the criteria. This instant reaction mechanism is pretty similar to front-running except it’s more like post-running: one cannot put the “buy” transaction before the “list on the auction” transaction, so it needs to happen immediately after. On a more technical level, there are several ways to implement this:
- Whenever you see a pending “listing” transaction, try to buy out the Kitty within the same block. You could either send the “buy” transaction with a slightly lower price (e.g. if the “list” transaction pays
25 gweifor gas, you can pay
24.999 gwei), or, alternatively, pay precisely the same. In the former case, you risk being just below the block cutoff threshold, and then your transaction would stay “pending” for hours if the activity spikes. In the latter case, you risk miners putting your “buy” transaction in front of the “list” transaction (since
gasPriceis the same, the order can be arbitrary and depends on miner software), which would result in our transaction failing.
- Wait until the “listing” transaction is confirmed, and send out the “buy” transaction right after with a very high gasPrice, ensuring confirmation within the next block.
You wouldn’t expect this cute game to be a particularly dense arena, but we had competitors who employed each of those options trying to snatch the Kitties! And since each of those options had its own benefits, we had to implement all of the strategies to have the highest chance (this can be done either the naive way, by running the 3 versions from 3 accounts, or by re-using the
nonce within the same account, but further technical details are beyond this story).
Another possibility we considered was the following: assume you want to buy a Kitty, and its price is slowly going down as determined by the linear time auction. Instead of buying it right away, one can wait until another contender appears and front-run their purchase, achieving lowest possible price. As much fun as it would have been to be such evil masterminds, the market was crashing too fast to warrant spending that much attention on any single big-ticket Kitty.
More than a month after the peak hype subsided, we received a pleasant surprise: somebody bought out Kitty #6 as well.
29 ETH was below the initial purchase price, but decent money nevertheless (plus Ethereum doubled in price at the time).
The remaining Kitty #8 gets Oleg’s undivided care and adoration. The Kitty has its own laptop stickers, t-shirts and even a custom-made silver pin. I hear it is about to get its own Instagram channel too.
In the end, it was a very hands-on lesson on speculative manias. I undershot and Oleg overshot, but both of us almost precisely doubled our money, which was a pretty amazing outcome. Yes, there is absolutely no guaranteed intrinsic value or price floor for imaginary Kitties. Nevertheless, one can still play this game and even win. And of course, it was practically impossible to predict where the top of the bubble would be, although we came pretty close.
As for my
~$5000 profit from this adventure, I decided to donate it to MCCME’s Summer Informatics School, an exceptional coding bootcamp in Russia where I studied as a high-schooler, as well as the Freedom of the Press Foundation. Here I doubled my money again thanks to Google’s generous Gift Match Program.