Many initial purchasers of the DAO tokens had clearly been anticipating its arrival and were ready to act on the first day. These users, one presumes, were more technically adept, which is hinted at by the significantly higher frequency of direct sends (orange bars) compared to createTokenProxy() (black bars) during the first few days of operation.

One might notice that as more purchasers appeared, the difference between the number function() calls relative to createTokenProxy() calls lessens. We believe this is due to the use of tutorials explaining how to purchase tokens. Many tutorials instructed users to use the Mist browser (as opposed to say the ‘geth’ command line interface) and from there to call into the createTokenProxy() interface. Of course, this is only conjecture, but it helps explain the growing relative use of createTokenProxy().

A Simple Mistake Leads to User Confusion

At the start of the creation period a single ether purchased 100 DAO tokens. Midway through the period, that ratio began a steady ten-day decrease until finally reaching 100 DAO tokens per 1.5 ether, where it remained for the last four days of the period. This behavior is explained well in this blog post and is further illustrated in the table below:

This table was generated by analyzing the following code. In the code, createTokenProxy() calls into a function called divisor(), the result of which, when multiplied by 20, gives the token/wei ratio. This factor is then multiplied by the amount of ether sent to the function (msg.value) to arrive at the number of tokens to award to the caller.

function createTokenProxy(address _tokenHolder) {

...

uint token = (msg.value * 20) / divisor();

extraBalance.call.value(msg.value — token)();

balances[_tokenHolder] += token;

...

}

The divisor() code looks like this:

// Return the divisor used to calculate the token creation

// rate during the creation phase. The number of tokens per

// wei is calculated as msg.value * 20 / divisor function divisor() constant returns (uint divisor) { if (closingTime — 2 weeks > now) {

// The fueling period starts with a 1:1 ratio

return 20; } else if (closingTime — 4 days > now) {

// Followed by 10 days with a daily creation rate

// increase of 5%

return (20 + (now — (closingTime — 2 weeks)) / (1 days)); } else {

// The last 4 days there is a constant creation rate

// ratio of 1:1.5

return 30;

}

}

Looking back at the bar chart above, one may notice the users’ behavior approaching May 15th, the first day of the price increase. As expected, activity increases as the price rise approaches. Notice, however, that the greatest activity occurs on May 14th, a full day before the price increase. (Each bar represents the activity between 9:00 am the previous day and 9:00 am on the current day, so the bar labeled May 14th ends at 9:00 am, May 14th — 24 hours before the first price rise).

The green-enclosed box in the table above helps explain this unexpected behavior, which is due primarily, we think, to an error on the DAO Hub website (see this DAOHub discussion and this reddit post). It seems the maintainers of the DAOHub website read the code wrong and made a miscalculation as to the first date of the price change.

Alternatively, one might say that the software code itself is in error. The somewhat confusing code of divisor() passes through a different path on May 14th (i.e. closingTime - 2weeks). However, oddly, it arrives at the same result (20). It is easy to see why the error on the website was made.

The extraBalance Account

Referring back to the source code above, notice the second line of the createTokenProxy code where the extraBalance account is funded with the amount over the 1:100 refundable tokens of the early adopters. This account was initially intended to hold the ‘profits’ of The DAO, which were later to be distributed pro-rata by token share; however, a decision was taken at some point to refund the original late purchasers with the exact amount of ether they sent. It is not clear, exactly, how that decision was made. It certainly was not voted on by token-holders as some people think it should have been.

Approve Calls

The undulating green area mentioned above represents calls to the approve function, one of the few functions that were not disabled during the Creation Period. We do see something a bit surprising here.

First, the existence of approve calls itself prior to the ability to actually make any transfers is unexpected, at least to this writer.

Secondly, and more surprisingly, is the regularity of these function calls and the fact that they came almost entirely from four addresses. It is our belief these calls were most likely exchanges practicing or testing their software prior to the start of the Operational period.