Exploring the Even Distribution Coin Offering Model

(second in a series of articles giving high level overviews of token sale model implementations)

I say we give up designing token sale models and allow the all-powerful PLINKO to decide who gets tokens

In my last article, I discussed token sales in general and talked about how we could find commonalities between all sales to help us create standard models. I also discussed the basic Direct Token Sale Model, where contributors send Ether to a contract and get a proportional number of tokens in return. As I explored in that article, there are inherent issues with that model of token sale, especially for sales where there is high demand for the tokens.

You can refer to that article for a more in-depth exploration of the pros and cons of that model, but to put it simply, while that model is simple to implement and easy to market, if your organization is expecting to make any significant interest and fundraising, it is a bad choice. Too many transactions can clog up the network, wealthy investors push out regular contributors with comically high gas prices, and tokens do not get distributed widely, which should be one of the highest priorities for any ICO.

It is obvious that different models are needed, which brings me to discussion of another well-known token sale model.

The Even Distribution Crowdsale Model

The Even Distribution, or address capped, Crowdsale model is a model which tries to ensure that everyone who wants to contribute to the sale gets an equal opportunity to. This is ensured by placing a cap on the number of tokens that a single address can purchase.

With this model, the owner also has the choice on whether to put a cap on the total ETH raise in the sale. If there is a raise cap, it gives participants an idea of what percentage of the tokens they are getting. If there isn’t a raise cap, the market gets to decide on the total valuation of the project based on how many buyers participate.

You can probably see that there are some problems with both of these models. With a cap, it shuts out any buyers that might come late to the sale, when enough addresses have participated to exceed the cap. With no cap, the contributors have no idea what the total valuation of the sale will be, therefore causing uncertainty about how many tokens to purchase.

I would have purchased you, my brother…. my captain…. my token

Luckily, the great team at 0x devised a version of this sale model that helps with some of these issues. When token sales have large demand, it is good to know how many people are interested in buying tokens before the token sale starts so that you can cater the sale to the demand. Therefore, in this model,

  1. The owner of the sale sets a maximum raise cap on the sale.
  2. Interested parties have a few days to register for the sale before the sale starts through an online portal, linking their address to a user and adding their address to the pool of registrants.
  3. When it comes time for the sale to start, the max raise cap of the sale is divided by the number of registrants to get the individual address cap.
  4. Each address is allowed to contribute no more than the calculated cap in the sale.
  5. It is inevitable that some addresses will forget to purchase tokens or decide to not participate, so after a specified time interval, the address cap increases to allow the rest of the tokens to be purchased by addresses who want more.

I’ll look at some pros and cons of this model before delving deeper into the implementation.

Pros:

  • Every address that wants to participate initially gets an equal opportunity to purchase tokens. High gas prices do not help much here because everyone has the rights to their allocation of the tokens no matter when their purchase goes through, as long as it is within the initial time period before the address cap increases.
  • In the first period of the sale, there is no incentive to be the first one to make a purchase, so there is a lower chance of network congestion and high gas prices.
  • If there is enough demand, ensures that there is a wide and even distribution of tokens. One of the main goals of token sales is to create a large network of potential users of their platform, so allowing the tokens to be distributed evenly is very helpful to this.

Cons:

  • Only addresses that registered early have a chance to participate, so if you found out about it during the sale, you are out of luck.
  • When the address cap goes up after the initial buy period, there is an incentive for getting there first, which can cause minor network congestion and high gas prices.
  • Large buyers can still buy a lot of tokens by creating multiple addresses, somewhat defeating the purpose, but this is harder to do and adding more addresses to the pool lowers to tokens per address anyway so there is a tradeoff.

There is a great analysis by Will Warren about how the 0x token sale performed using a variety of metrics. One interesting takeaway was that almost everyone who registered did in the first day of the registration window. They were able to notice Sybil attacks happening in the later days before deciding to cut the registration period short.

Another observation is that even though registrants have through the whole first period of time to purchase their tokens, there still is a high percentage of them who try to purchase quickly on the first day, causing some network issues. Becuase of this, it is probably a good choice to keep the time period in between cap changes relatively short, like 1–2 days depending on the demand of the sale.

Implementation

Now we will start a brief discussion about how a libary can implement this crowdsale by exploring what metrics all crowdsales of this type should have in addition to the metrics that I discussed all crowdsales share in my previous article.

  • Mechanism to allow users to register and unregister. Most sales will only allow user registration for a short period before the sale, but registration could be used throughout the sale if there is a static cap per address. Users will register on a website provided by the owner and the owner submits the registration to the smart contract.
// pseudo-code
function registerUser(address registrant) {
require(sender==owner)
require(sent during the registration window)
require(user is not already registered)
// set registrant status to registered
// add registrant to number of users registered
}
function unregisterUser(address registrant) {
require(sender==owner)
require(sent during the registration window)
require(user is already registered)
// set registrant status to unregistered
// subract registrant from number of users registered
}
  • Mechanism to calculate the address cap based on how many users registered pre-sale.
function calculateAddressCap() {
require(sender==owner)
require(registration time is over, but sale hasn't started)
require(this can only be called once)

// divide the raise cap by the number of registrants
// save the result to the current address cap
}
  • Mechanism for users to submit purchases. Since the contract lies dormat when nobody is interacting with it, this function also handles increasing the price of the token, if needed, and increasing the purchase cap per addres.
function sendPurchase() {
require(purchase is valid)

// update address cap if the time interval has passed
// update token price if the time interval has passed

// calculate number of tokens purchased
// refund excess ETH
// give user tokens
}

And that is about it! You can see how we implemented it here. We have done extensive testing on the model and feel very confident in its security and functionality, but still welcome any feedback on how to make it better.

At Modular, we are working on creating open source, community audited, deployed libraries for Ethereum, and we are including this style of customizeable crowdsale in our libraries. In accordance with the rules I laid out in the first article, we have created a base crowdsale library that specific crowdsale implementations “inherit”. It includes all the common variables and functions mentioned last time. We also created an implementation of the crowdsale library described in this article for even distribution crowdsales which utilizes the base library to give developers a tested resource in creating their own crowd sale contracts.

You can see our libraries on our Github. We already have libraries for a large variety of applications and are actively working on building out libraries for different ICO models. We plan to have libraries available for each major model as I release these articles every couple of weeks. Next time, I’ll be discussing the Interactive Coin Offering Model that we have started working on with TrueBit and some of the best Solidity Developers in the community!

We are all constantly learning and love to get feedback from the community, so if you see anything in this post or on our Github that needs clarification or improvement, we would love to hear from you in the comments. If you want to get involved, you can also contact us at modular.network!

References:

Will Warren, Analyzing the 0x Token Sale, https://blog.0xproject.com/analyzing-the-zrx-token-sale-a94b8642c78e

Smart Contract Engineer at Dapper Labs, working with Cadence, the best language for smart contracts!