How to implement a Fair and Secure ICO
A technical look into the inner workings of our own IGNIS crowdfunding campaign which you can duplicate for your own NXT based ICO for a fraction of the cost of other solutions
Development of smart contracts for an Ethereum ERC20 token is expensive. Typical costs include around $20K for the development of the smart contracts and another whopping $50K for the security review. It sounds outrageous initially, but I think this is understandable, after all each Ethereum token is developed from scratch to the specification of the ICO team and with so many security problems with smart contracts, surely the security reviewers are in high demand and can charge as much as they like.
In a previous article, I explained how NXT can be used as a cheaper and safer alternative for ICO platform. However I did not specify the exact details and I recently received so many questions that I decided this needs more clarification.
Assuming you are not familiar with NXT, your best approach is simply to follow the structure of our own IGNIS ICO to the letter, this will provide you a working and secure crowd funding solution for much more affordable R&D costs.
The rest of the article is a bit technical. You have to be somewhat familiar with NXT and know how to run a node and understand the APIs, there is no way around this. I won’t explain this in this article. I suggest you start from our nxtwiki. I can assure you that it’s as simple as any blockchain platform and probably much simpler.
The basic building block of the JLRDA token used by the IGNIS ICO was a token of type Controllable Currency. To start with I’d like you to read the monetary system official documentation, yes I know this thing is long and verbose but you do want to raise millions and don’t want to pay the ETH guys or get hacked, do you? So read the damn thing please.
After you read the documentation, I can tell you is short that a Controllable Currency can only be transferred to and from the issuing account, and if also exchangeable only the issuing account can publish offers. These properties makes it an excellent tool for crowdfunding. The restriction on transfers makes sure that buyers cannot move the tokens around and the restriction on issuing sell offers makes sure you have control over the price levels so no one else can provide a better price while you follow your ICO schedule.
To see which currency properties we used for the IGNIS ICO see the JLRDA currency on the NXT mainnet and always issue your currency with 4 decimal positions.
Currencies can be traded using the existing NXT wallet exchange booth interface. However this interface is too complex for the casual ICO buyer, therefore we designed a special page for the ICO that only supports a single function to buy the currency. You will need to implement a similar page and either add it as a wallet plugin or simply post it into your ICO web site. Don’t build this page from scratch, reuse the existing page we built for our own ICO. Download and install NXT 1.11.9 (don’t use a later version since some of this code was removed) then look at the ignis.html file (./html/www/html/pages/ignis.html) and the functionality which supports it in nrs.monetarysystem.js starting from line 1600 (./html/www/js/nrs.monetarysystem.js). Based on the ignis.html code, develop your own ICO page either as a modified version of NXT (our client code is released under the MIT license so you are allowed to do this) or as a wallet plugin which will allow other NXT nodes to support your ICO but will add some complexity to your development process. You can further simplify the ICO page as you like. For example you don’t have to include support for the Shapeshift and Changelly exchanges on this page like we did.
For each ICO round issue a single exchange offer for your currency according to your ICO schedule. Use the NXT wallet interface for this. You only need to offer the currency for sale, specify 0 values in the buy side. Look for example at transaction 12339997342493732668 on NXT Mainnet to see one of the offers we issued to sell 1 JLRDA for 0.76 NXT. Make sure the expiration height aligns with the ICO schedule. Recall that in NXT a block is generated every minute on average.
When selling your tokens using an exchange offer, the reward is received in NXT, therefore the account which issued the currency will accumulate large amount of NXT, however you should not place this account under account control because this will interfere with the scheduled transactions operation (explained below). Instead prepare another account secured by account control and move funds collected in ICO regularly to this account.
When choosing a name for your token. Make this token name as simple as possible to make it harder for scammers to confuse users into buying their own fake tokens. In retrospect, the name chosen for our own token JLRDA was problematic since some users where scammed into buying a token named JRLDA for example. So make sure your token name is simple and even consider paying the additional fee for a 4 letter or 3 letter currency.
Randomization and Scheduled Transactions
In case your ICO is popular, there will be over demand when you issue the first batches for sale. There is always a risk that a single buyer will buy the whole batch by matching your unconfirmed sell offer before users will be able to see the sell offer in the UI.
In order to mitigate this risk, and make sure everyone has fair chance to buy your token, you should let your users schedule their buy requests before you offer the currency for sale using the scheduled transactions feature. This part is optional, you don’t have to support it in your ICO page but if you don’t, you give the tech geeks an unfair advantage over all other buyers.
In order to achieve this, your code should load the available exchange offers when your user submits the buy transaction. If none exists, you should add scheduled=true data to the buy button, for example $(“#buy_ignis_button”).data(“scheduled”, true); As a result when a user submits a buy transaction it will be stored in the node memory and not submitted to the blockchain yet.
To see how this worked for the IGNIS ICO review the processOffers() function in nrs.monetarysystem.js of NXT 1.11.9 and mimic this functionality. This will submit a scheduled transaction which will remain in the node memory. This scheduled transaction will only get broadcast to the blockchain at the moment the node sees your unconfirmed exchange offer transaction. This will create a fair competition between all buyers. In case the exchange offer was already submitted, your code should set scheduled=false data and thus will submit a normal currency buy transaction.
To set the price of the scheduled buy transaction we used an account property of the currency issuer account and modified it to reflect the current price level of the token. We then used this account property to set the rate of the scheduled buy requests. See nrs.monetarysystem.js line 357
Testing your solution
Setup an NXT testnet node and use it to test your solution before deploying it mainnet. You should treat this as a development project and use the normal best practices for testing and code review. Always assume that hackers and scammers will be watching your code for bugs because rest assured they will.
In this article I explained in detail the inner workings of the IGNIS ICO in order to allow developers to mimic this process in their own NXT based ICO. Using the same technique you can perform a safe and fair ICO at a fraction of the cost and effort it would take to implement it on any other blockchain platform.
In my next article I will explain how to allow users to invest in your NXT based ICO using other crypto-currencies and still register the ICO tokens on the NXT blockchain.
In the 3rd article in this series, I’ll explain how you can use Ardor to further improve this technique and create an ICO which conforms to KYC/AML requirements.