TokenCard Tech Roundup and ERC20 Crediting

The TokenCard creation event yesterday was overwhelming and staggeringly successful, but there are a number of areas for improvement, and one bug that needs fixing before token transfers can start.

I want to give a quick review of the event as a whole, and then talk about the bug and next steps.

REMINDER AND WARNING All exchanges and individuals purporting to transfer TKN are not able to do so now; the TKN ERC20 contract address has not been published yet. Some decentralized exchanges have "guessed" an address -- this is not the correct address. These tokens have no value in the TKN ecosystem. Only tokencard.io should be relied on for the ERC20 token address.

First Takeaway - Pay Attention to Gas and the Estimator

We briefly broke the Blockchain; TokenCard events and transfers took over Ethereum for 30 minutes and that slowed everything down. One thing we had considered, but not carefully enough, was gas and gas estimation for TokenCard contributors. We expected that there would be demand to contribute, but internally had no idea that we would see the level and intensity of demand that contributors showed.

Internally we had guesses ranging from four or five hours to seven days for the duration of the crowdsale; instead it was roughly 28 minutes, in essence, everything that we thought might happen in a great scenario happened very very quickly.

This is humbling -- Mel and David are blown away by the support -- but I'm here to do a tech debrief, so I'll get into the nerd talk without further ado.

The ERC-20 Crediting Bug

We will publish a full root cause analysis soon, but it won't be a long document. In summary, the server calculating the value of a transfer has the lines:

var eighteen = new(big.Float)
eighteen.setString(10e18)

Astute (or even just basically curious) readers should see the bug immediately -- 10e18 is 1 with 19 zeros on the end. Much, much better would have been 1e18. For some context, 10**18 is the correct way to get one with eighteen zeros in some languages. But not using GoLang's BigInt package (needed for numbers this large).

While the smart contracts were extensively tested, the server calculating ERC20 transfer values was under development until right before the crowdsale, and we used the same incantation (10e18) for all testing and for the final crediting.

DGD has nine zeros of decimals, and true to form I see nine.setString(10e9) -- we were consistently wrong at least!

There is no excuse for this, it was an engineering error.

Remediation

Because the specifications for the crowdsale were that tokens contributed not affect the cap (Mel and David were concerned they would receive too many tokens that were thinly traded), the smart contract used in the token creation event has two paths for minting tokens. The first path comes in through the fallback function and is triggered by any ETH sent.

The second path comes through depositToken and emits a special event just for token purchases, including a reference number and the number of tokens that were used to calculate out the ETH value of the deposit. Of course each ERC20 contract emits its own Transfer logs as well. This makes determining the TKN balance expected for each contributor very easy to calculate.

Combined with the ERC20 events, getting an audit log together was simple. We filtered on the deposit token logs and the ETH credit logs and have a full list of all deposits, including the base number used for calculation.

We then followed a series of steps published below to confirm the correct amounts. We are going to remain cautious and thoughtful, and compare our results to those of an outside firm, but assuming they are correct, we will publicize the ERC20 contract address shortly.

Next Steps

We made best efforts to get the ERC20 token contract in place at time of launch, but correct fulfillment of the contribution terms is our number one priority, so we will be doing a numeric audit before we announce the token contract's Ethereum address.

We'd also love someone to check our work - we currently have one outside group reviewing the methodology and recreating the numbers to make sure that two independent sets of eyes agree on the tokens granted.

If any other groups would like to calculate the precise numbers as a third check, you're welcome to do so; the precise calculation steps are detailed below.

Precise Steps For Token Calculations

  1. Get the first block in which the smart contract accepted ETH. This is the start.
  2. Get the last block in which the smart contract accepted ETH. This is the end.
  3. For each block from start to end, get each ERC20 transfer event from: REP, SWT, DGD, MKR, SNGLS, MLN, GNT, UNICORNS
  4. Credit them as follows:
    • REP: $16.12
    • GNT: $0.203
    • MKR: $75.40
    • DGD: $30.408
    • SNGLS: $0.1029
    • MLN: $36.70
    • SWT: $1.38
  5. The Ethereum Price for the launch is $75.00
  6. TKN has 8 decimals.
  7. SNGLS have 0 decimals.
  8. DGD have 9 decimals.
  9. All others have 18 decimals.
  10. For each ERC20 transfer event in the list, calculate the ETH value (this is the step we had trouble with at launch)
  11. Grant 100 TKN per the calculated ETH value

Edit: to be clear, this is only the process for ERC20 token credit transfers. Bonus calculations for ETH transfers were calculated on the Blockchain correctly and will be credited precisely as calculated.

Second Edit: UNICORNS was a joke; apparently to some in the community a bad one - my apologies. We expected to get random tokens interested in testing our smart contract, and thought it would be fun to reward anyone with Unicorns. No unicorns were sent during the token creation period, although we inexplicably did receive Guppys and Edgeless.

Failed Transactions

A large number of transactions failed because of gas costs. I would split those transactions into two categories -- those that sent the default amount of gas for a wallet, say 21,000, and those that used an incorrect gas calculation, a number that might look like 93,432, but ultimately wasn't enough gas to complete.

There are some good reasons a wallet might not be able to estimate gas well in a time of high transaction volume -- if each transaction adds a little bit of additional cost for future transactors, then you could easily have a world in which only those who manually override the gas estimation to a high number will get through. This seems to have happened more than expected, but isn't the only thing -- some wallets seemed to just have gotten it completely wrong.

These transactions are doubly bad, since they post and are mined but throw -- they pollute the Blockchain and they tie up funds until the throw happens.

In the future, New Alchemy will be working to get the gas costs down as low as possible for token creation events, and have as a development requirement that the contribution functions are easily estimable even under load. Because of the current gas limits on Ethereum, it's possible we will recommend very vanilla holding contracts for token sales until Metropolis is out and can be tested in this way.

Next Update In ..

We will update in 24 hours with information; internally we are not expecting this process to take long, but we want to make sure we do it right. Thank you all for the encouraging words -- we're excited to see the TKN token out in the wild, and find out what people are doing with them.

About New Alchemy

New Alchemy provides technology and strategy resources for the TokenCard project. Contact us with any questions: [email protected]

Peter Vessenes

Read more posts by this author.

Subscribe to Peter Vessenes

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!