CryptoKitties Traction Part 1/5 – Revenue Analysis

TLDR; We are writing a 5-part series on “10x analytics” using the CryptoKitties’ blockchain dataset. We’ve combined on-chain Ethereum transaction data with off-chain API data to deep-dive into their business model and revenue metrics behind the game. We’ve also open-sourced the SQL code behind the analysis if you want to follow along. 😍

CryptoKitties is one of the most popular games on the Ethereum blockchain. Players collect and breed kitties, which are unique digital assets. Ownership is tracked via the Ethereum blockchain and a network of smart contracts allow for buying, selling and breeding of these digital assets.

Fortunately for us, the game is completely decentralized and all the player data lives on the Ethereum blockchain. The data on the blockchain is pretty disorganized, but we can use a tool like Covalent to make that data more understandable to a mere data analyst like myself.

The data behind CryptoKitties

CryptoKitties uses a Genetic Algorithm to create new kitties. New kitties are created in two ways:

  1. A clock periodically introduces new kitties to the blockchain. These are Generation 0 kitties and are owned by the developers. When these kitties are “minted” they are put up for auction – and the winning bid goes to the developers. In a way, this is “free money” for the developers because they were able to continuously create generation 0 kitties. The last ever generation 0 kitty was generated at the start of Dec ‘18 and there are a total of 38,015 generation 0 kitties on the blockchain.

  2. Players are able to put up their kitties for a mating auction (known as a siring auction), and upon a successful bid, a new generation kitty is introduced to the blockchain.

Each kitty has its own unique 256-bit unique genome code and are known as Non-fungible Tokens (NFTs) or crypto-collectibles.

Date Attribute Value
Jan-15-2019 Total number of Gen 0 kitties 38,015
Jan-15-2019 Total number of kitties 1,343,159

The CryptoKitties Business Model

To understand CryptoKitties’ business model, you’ll have to understand their game mechanics. The developers behind CryptoKitties make money in three ways:

  1. Gen 0 sale – A smart contract periodically introduces new kitties to the blockchain. These “Gen 0” kitties are owned by the developers and put up for sale in an auction. When the Gen 0 kitty is successfully sold, the developer gets the bid price.
  2. Sale auction fee – Players are able to put up their kitties for sale in an auction. Upon a successful bid, a fee is charged by the developers. The Gen 0 sale is a specific instance of this game mechanic.
  3. Siring auction fee – Players are able to put up their kitties for siring in an auction so kitties from other players can mate with them. Upon a successful bid, the kitty becomes pregnant and a fee goes to the developers. Another player can help “giveBirth” and is given a reward (but that fee doesn’t go to the developers.)

We’ll label these three revenue streams as: gen0_sale, sale_auction and siring_auction. As the exchange of monetary value is always done through a Dutch auction, we’ll be taking a closer look at just the successful ones.

There are two ways of looking at the revenue numbers:

  1. from the context of the developers ➡ helps them build a better game that monetizes well
  2. from the context of a player ➡ helps a player be more strategic with their trades

We’ll study the business model using a series of questions and a corresponding analysis.


Analysis 1: CryptoKitties, a Million or a Billion dollar business?

The auction mechanism is the linchpin of the CryptoKitties business model. Fortunately, the CryptoKitties smart contract puts all successful auctions with the winning bid price on the blockchain.

Let’s first calculate if the monies involved are in the thousands, millions or billions of dollars.

Almost an eight-figures business! The marketplace game mechanics through the auction system pushed just over nine million US dollars in 2018. Ofcourse, we’ll want to dig a lot deeper to see if the volumes are growing or shrinking and if the collapse of Ethereum prices has had an adverse effect or not.

Analysis 2: CryptoKitties, a growing business?

We chart the money flowing through the system in both Ether (Ethereum’s native currency) as well as US dollars. The value of Ether had dropped over 80% in 2018 and that is clearly visible when we convert the Ether values to USD.

It seems like they’ve had two spikes around September 2018 and November 2018 – perhaps because of a marketing push or a new product feature. Unfortunately, when converted to USD the volume is diminished due to the lower Ether prices.

Analysis 2a: CryptoKitties, a growing user base?

Another way to look at a growing business is to look at the number of players. Doesn’t matter if your per-user revenue is dropping, you can still make it up in volume when your user base is growing. In fact, that’s a sign that you’ve reached the masses.

We are going to be devoting an entire report on the behavior of CryptoKitties’ user base. Stay tuned!

Analysis 3: What is the breakdown by CryptoKitties’ revenue streams?

The next analysis deals with breaking down the auction volumes into various revenue buckets for the developers – specifically, gen0_sale, sale_auction andsiring_auction.

The charts above show that the consistently around 80% of their revenue came from the generation 0 kitty sales. As generation 0 kitties are no longer created, that revenue stream has been shut off completely. My opinion is that while this is bad for the developers (i.e., they make less money), overall it’s good for the long term health of the game because:

  1. Increases urgency for the developers to improve the game mechanics beacuse that’s the only way they can increase their own revenues.
  2. Increases the scarcity of generation 0 kitties when players know that no new generation 0 kitties are going to be created.

Analysis 4: How much money have the players made so far?

Let’s take a page from Apple’s playbook – I like how they describe their ecosystem as “Apple has paid out $120 BILLION to developers since 2008.”

The players have made (revenue, not profits) a little over 8.7 million dollars in 2018. Not bad at all!

Analysis 4a: What is the distribution of payouts to the players?

On the Apple App Store, it’s common knowledge that 94% of the revenue goes to the top 1% of the publishers. We see similar distributions on the Steam platform, the Facebook platform when it launched, etc.

For CryptoKitties, 95% of the players make less than 1 ETH over their lifetime.

On the other end of the spectrum, the “whales” (high earners who earn more than 10 Eth) make up less than 1% of the user base and that’s consistent with benchmarks across the gaming industry. We’ll be digging deeper into the behavior of these whales in a future post.

Additional revenue questions

We’ve only scratched the surface of the kinds of questions we can answer. Here’s more food for thought:

  1. How many Generation 0 kitties are still up for auction by developers and not claimed by other players? It would be interesting to understand if there were a decreasing demand for these kitties because the market was flooded.

  2. Now that Generation 0 kitties are no longer being created, are the volumes attributed to the auctions of kitties higher or lower? Another way of thinking about this is if your generation 0 kitty is an asset, how liquid is it?

  3. Since we know the two revenue streams, which one is more sticky and corresponds to a longer game play? What should the developers market more?

  4. Price discovery and liquidity. The matching algorithm currently is a simple Dutch auction. Can we find blocks of illiquid kitties and bundle them to make them more appealing? What is the ratio of successful auctions to auctions created and how is that trending over time. A key sign of the health of the game and the consistency of the developer’s revenue streams.

  5. Everything to do with profits. What has been the most profitable generation of kitties? Or any other genetic trait like color, etc.

  6. Everything to do with taxes. Are the players paying taxes on their gains? Are they short-term or long-term?

  7. How are these numbers looking for other localized versions (i.e., Chinese) of the game?

What’s next

This is part 1 of a 5 part series on analyzing CryptoKitties using the data on the blockchain. The other parts are:

  1. CryptoKitties Traction – Revenue (this post)
  2. CryptoKitties Traction – Retention
  3. CryptoKitties Traction – Reach
  4. CryptoKitties Traction – Ratios
  5. CryptoKitties Traction – Growth Opportunities

Appendix: The SQL

Here’s the SQL code you can use as a template for your own analysis. Our product Covalent provides direct SQL access to Ethereum-backed assets and protocols, so you’ll need something like our tool for the underlying data.

A. Number of kitties by generation cumulative over time

 1 2 3 4 5 6 7 8 910111213141516171819202122232425
SELECT date, CASE
                 WHEN generation = 0 then 'Gen 0'
                 WHEN generation = 1 then 'Gen 1-10'
                 WHEN generation = 11 then 'Gen 11-20'
                 WHEN generation = 20 then 'Gen 21+'
             END AS generation,
             count,
             sum(count) over (
     ORDER BY date ASC rows between unbounded preceding AND current row) AS cum_count
FROM
  (SELECT date_trunc('month', created_at) AS date,
          CASE
              WHEN generation = 0 then 0
              WHEN generation > 0
                   AND generation <= 10 then 1
              WHEN generation > 10
                   AND generation <= 20 then 11
              WHEN generation > 20 then 20
          END AS generation,
          count(*)
   FROM kitties.metadata k 
GROUP BY 1,
         2
   ORDER BY 1,
            2) x

Analysis 1: CryptoKitties, a Million or a Billion dollar business?

 1 2 3 4 5 6 7 8 91011
SELECT sum(t.logged_total_price) AS total_auction_volume,
       sum(t.logged_total_price * (ep.high + ep.low) / 2) AS total_auction_volume_usd
FROM
    (SELECT date_trunc('day', block_signed_at) AS date,
            logged_total_price / (10^18) AS logged_total_price
   FROM kitties.log_events_auction_successful s
   JOIN kitties.block_log_events b
     ON s.block_id = b.block_id
     AND s.log_offset = b.log_offset) t
JOIN ethereum_prices ep
  ON t.date = ep.date

Analysis 2: CryptoKitties, a growing business?

 1 2 3 4 5 6 7 8 910111213141516171819
-- how much ether is flowing through the system

SELECT date_trunc('month', x.date) AS date,
       sum(x.logged_total_price) AS auction_price,
       sum(x.logged_total_price_usd) AS auction_price_usd
FROM
  (SELECT t.date AS date,
          t.logged_total_price AS logged_total_price,
          t.logged_total_price * (ep.high + ep.low) / 2 AS logged_total_price_usd
   FROM
       (SELECT date_trunc('day', block_signed_at) AS date,
               logged_total_price / (10^18) AS logged_total_price
      FROM kitties.log_events_auction_successful s
      JOIN kitties.block_log_events b
        ON s.block_id = b.block_id
        AND s.log_offset = b.log_offset) t
   JOIN ethereum_prices ep
     ON t.date = ep.date) x
GROUP BY 1

Analysis 2a: CryptoKitties, a growing user base?

 1 2 3 4 5 6 7 8 9101112131415
SELECT date, count(*)
FROM
  (SELECT date_trunc('month', block_signed_at) AS date,
          logged_from,
          count(*)
   FROM kitties.log_events_transfer c
   JOIN kitties.block_log_events s
     ON c.block_id = s.block_id
     AND c.log_offset = s.log_offset
   WHERE block_signed_at >= '2018-01-01'
     AND block_signed_at < '2019-01-01'
   GROUP BY date, logged_from
   ORDER BY 3 DESC) x
GROUP BY date
ORDER BY date

Analysis 3: How much money have the developers made so far?

 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
WITH transactions AS
  (SELECT *
   FROM ck_traces
   WHERE transaction_hash in
       (SELECT transaction_hash
        FROM kitties.blockchain_traces
        WHERE to_address = '0xb1690c08e213a35ed9bab7b318de14420fb57d8c'
          AND to_address not in ('0x06012c8cf97bead5deae237070f9587f8e7a266d',
                                 '0xa21037849678af57f9865c6b9887f4e339f6377a',
                                 '0xba52c75764d6f594735dc735be7f1830cdf58ddf',
                                 '0xbb1e390b77ff99f2765e78ef1a7d069c29406bee')
          AND trace_address = ''
          AND status = true )
   ORDER BY block_number,
            trace_address)
  (SELECT date_trunc('week', t.date) AS date,
          'gen0_sales' AS rev_type,
          sum(t.take_eth) AS take_eth,
          sum(t.take_eth* ((ep.high + ep.low) / 2)) AS take_usd
   FROM
     (SELECT date_trunc('day', block_timestamp) AS date,
             sum(value) / (10^18) AS take_eth
      FROM
        (SELECT block_timestamp,
                to_address,
                from_address,
                value,
                transaction_hash
         FROM kitties.blockchain_traces
         WHERE from_address = '0xb1690c08e213a35ed9bab7b318de14420fb57d8c'
           AND to_address in ('0x06012c8cf97bead5deae237070f9587f8e7a266d',
                              '0xa21037849678af57f9865c6b9887f4e339f6377a',
                              '0xba52c75764d6f594735dc735be7f1830cdf58ddf',
                              '0xbb1e390b77ff99f2765e78ef1a7d069c29406bee')
           AND status = true
           AND value > 0 ) x
      GROUP BY 1
      ORDER BY 1) t
   JOIN ethereum_prices ep
     ON t.date = ep.date
   GROUP BY 1
   ORDER BY 1)
UNION ALL
  ( SELECT date_trunc('week', t.date) AS date,
           'siring_sales' AS rev_type,
           sum(t.take_eth) AS take_eth,
           sum(t.take_eth* ((ep.high + ep.low) / 2)) AS take_usd
   FROM
     (SELECT date_trunc('day', block_timestamp) AS date,
             sum(value) / (10^18) AS take_eth
      FROM
        (SELECT block_timestamp,
                from_address,
                to_address,
                value,
                transaction_hash
         FROM kitties.blockchain_traces
         WHERE from_address = '0x06012c8cf97bead5deae237070f9587f8e7a266d'
           AND to_address in ('0xc7af99fe5513eb6710e6d5f44f9989da40f27f26')
           AND value > 0
           AND status = true ) x
      GROUP BY 1
      ORDER BY 1) t
   JOIN ethereum_prices ep
     ON t.date = ep.date
   GROUP BY 1
   ORDER BY 1)
UNION ALL
  ( SELECT date_trunc('week', t.date) AS date,
           'sale_auction' AS rev_type,
           sum(take_eth) AS take_eth,
           sum(take_eth * ((ep.high + ep.low) / 2)) AS take_usd
   FROM
     (SELECT date_trunc('day', block_timestamp) AS date,
             sum(CASE
                     WHEN trace_address = '' then value
                     ELSE -1.0 * value
                 END) / (10^18) AS take_eth
      FROM kitties.blockchain_traces
      GROUP BY 1) t
   JOIN ethereum_prices ep
     ON t.date = ep.date
   GROUP BY 1
   ORDER BY 1)

Analysis 4: How much money have the players made so far?

 1 2 3 4 5 6 7 8 91011121314151617181920212223242526
SELECT date_trunc('week', p.date),
       sum(p.payout_eth) AS payout_eth,
       sum(p.payout_usd) AS payout_usd
FROM
  (SELECT x.date,
          sum(payout_eth) AS payout_eth,
          sum(payout_eth * ((ep.high + ep.low) / 2)) AS payout_usd
   FROM
     (SELECT date_trunc('day', block_signed_at) AS date,
             encode(logged_winner, 'hex'),
             (logged_total_price / (10 ^18)) AS payout_eth
      FROM kitties.log_events_auction_successful s
      JOIN kitties.block_log_events e
        ON s.log_offset = e.log_offset
        AND s.block_id = e.block_id
        WHERE ('0x' || lower(encode(logged_winner, 'hex'))) not in ('0x06012c8cf97bead5deae237070f9587f8e7a266d',
                                                                    '0xa21037849678af57f9865c6b9887f4e339f6377a',
                                                                    '0xba52c75764d6f594735dc735be7f1830cdf58ddf',
                                                                    '0xbb1e390b77ff99f2765e78ef1a7d069c29406bee')
            AND block_signed_at >= '2018-01-01'
            AND block_signed_at < '2019-01-01' ) x                                                                  
   JOIN ethereum_prices ep
     ON x.date = ep.date
   GROUP BY 1) p
GROUP BY 1
ORDER BY 1

Analysis 4a: What is the distribution of payouts?

 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435
SELECT CASE
           WHEN bin = 0 then '0-0.01'
           WHEN bin = 1 then '0.01-1'
           WHEN bin = 2 then '1-5'
           WHEN bin = 3 then '5-10'
           WHEN bin = 4 then 'Rest'
       END AS bin,
       cnt
FROM
  (SELECT CASE
              WHEN payout_eth < 0.01 then 0
              WHEN payout_eth < 1 then 1
              WHEN payout_eth < 5 then 2
              WHEN payout_eth < 10 then 3
              WHEN payout_eth >= 10 then 4
          END AS bin,
          count(*) AS cnt
   FROM
     (SELECT encode(logged_winner, 'hex') AS winner,
             sum(logged_total_price / (10^18)) AS payout_eth
      FROM public.ck_log_events_auction_successful s
      JOIN public.ck_block_log_events e
        ON s.log_offset = e.log_offset
        AND s.block_id = e.block_id
      JOIN ck.kitties k
        ON s.logged_token_id = k.id
      WHERE ('0x' || lower(encode(logged_winner, 'hex'))) not in ('0x06012c8cf97bead5deae237070f9587f8e7a266d',
                                                                  '0xa21037849678af57f9865c6b9887f4e339f6377a',
                                                                  '0xba52c75764d6f594735dc735be7f1830cdf58ddf',
                                                                  '0xbb1e390b77ff99f2765e78ef1a7d069c29406bee')
        AND logged_total_price / (10^18) < 10
        AND block_signed_at >= '2018-01-01'
        AND block_signed_at < '2019-01-01'
      GROUP BY 1) x
   GROUP BY 1) y
Posted in 10x Analytics Cryptokitties

Be the first to know about new research