Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
Many high-profile ICOs launched last year amidst a swarm of criticism. The entire community was looking for a method to run token sales on Ethereum in a more fair and safe manner. To achieve these goals, Jason Teutsch and Vitalik Buterin authored the technical paper for the Interactive Token Sale protocol, which got a lot of attention. This was finally an ICO model that had the potential to give participants a guarantee of valuation and participation. Here are a couple different articles providing a rundown of how it works.
In this article, I want to walk you through how we at Modular, with the help of the great team at TrueBit and a few other amazing developers and thinkers in the community, built and optimized the first implementation of the protocol. Iâll also explore the challenges we faced along the way.
Prerequisites
The interactive crowdsale protocol allows participants to submit an ETH payment for tokens along with a personal valuation cap.
ETH Contribution: The Ether that the participant sends to the sale with the expectation of receiving tokens in return. These ETH payments are summed throughout the sale to equal the total sale valuation.
Total Sale Valuation: The sum of all the active bids in the sale or total amount of ETH raised, not to be confused with the total valuation of the token or project itself, as the sale will only handle a percentage of the total tokens minted. This will fluctuate throughout the sale until the end, when it will reach an equilibrium determined by the participants.
Personal valuation cap: An indication by each participant that they are willing to leave their token purchase in the sale as long as the maximum total sale valuation does not exceed their personal valuation cap. If, at the very end of the sale, the total sale valuation is greater than their personal valuation cap, the participantâs bid is refunded.
There are two stages to the sale. In the first stage, participants are allowed to submit and withdraw bids at will. Early bidders receive bonus tokens as part of their purchase. This bonus decreases linearly until the end of the first stage. Participants can manually withdraw their submitted bid and receive a linearly decreasing percentage of their ETH back. The ETH that is withheld from this refund still goes towards purchasing tokens for this participant, but forfeits a percentage of the early contribution bonus on these remaining, permanently committed tokens. See section 5.3 of the technical paper for an explanation of why these two penalties are necessary. The ETH that was withheld still goes towards the crowdsale in the form of a token purchaseâââthis penalized ETH is no longer able to be withdrawn. In this stage, the total sale valuation will fluctuate as bids are submitted and withdrawn.
Since the total sale valuation can move up and down in the first stage due to deposits and withdrawals, every bid is still âactiveâ even if a personal valuation cap is exceeded.
The transition between the first and second stage is termed the âwithdrawal lock.â In the second stage, submissions are still allowed, but all active bids are committed for the duration of the sale. Withdrawing ETH refunds are only allowed if the participant has a minimal bid, meaning their personal cap is less than the total sale valuationâââin other words, excluded from the sale. These withdrawals receive complete refunds because their contributions have no effect on the sale. After the withdrawal lock, the total sale valuation will monotonically increase, meaning it can only stay the same or increase.
To recap:
That was only a basic explanation to provide some background information on interactive token sales. In this article, I am assuming that readers know the general basics of how the sale works. You can read some of the articles I linked above in addition to the technical paper to get a better handle on some intricacies of the protocol. Rob Bent wrote a great summary here:
Interactive Coin Offering â A Protocol Explained
If you have read any of my or C. Brownâs posts or checked out our repository or website, you know that weâre creating secure standard libraries that are easy to understand and use right away. In that vein, we decided to build the Interactive Token Sale implementation on top of our base Crowdsale Library, which contains proven functionality and storage structs that are common to almost all crowdsale models, so that anyone can utilize them as library functions. You can read more about this library in my first post:
Finding Common Ground Among Unique Token Sale Models
To store the sorted personal valuation caps, we needed a data structure that could be sorted in increasing order that also allows easy insertions and deletions. Sounds like the description of a linked list! We have a library for that also that we made based on the great work Darryl Morris did in his implementation here, creating a linked list that is built using a uint256 => bool mapping. You can read more about how that works in my last post:
Circular Linked List in Solidity!
First Draft Details
When we first built the Interactive Token Sale implementation, we took what was written in the technical paper and directly translated it to smart contract form.
Obvious Issues
Implementing theoretical work in code comes with tradeoffs and issues that donât necessarily apply in theory. Also, smart contract programming is a new paradigm which creates issues that normal code doesnât necessarily have, most notably around cost of execution, i.e. gas use.
Removing Bids from the sale costs too much gas:
In the technical paper, it was specified that when the total sale valuation surpasses a bidderâs personal valuation cap, their bid should be removed from the sale. This seemed fairly simple, and we implemented this functionality in the submitBid function as a loop that traverses the submitted bids and removes any bids with personal valuation caps below the total sale valuation, and sends refunds until the total sale valuation has gotten back to be less than all bids that have been submitted. If you are interested in seeing the code, check out the implementation here.
As you can probably see, this poses a potential problem of unchecked gas usage. If a user submits a large bid, there could be many bids that need to be removed, potentially costing the bidder a lot in gas fees or even exceeding the block gas limit!
Itâs imperative that all participants in the IICO protocol are treated equally. Participants should not be penalized with high gas usage for the behavior of other users. Therefore, we needed to completely redesign how the sale keeps track of bids.
Redesign
The redesign constantly calculates the cutoff for participation in the sale and keeps a record of which bids are valid and which arenât, without automatic refunds. After the sale ends, participants can withdraw their tokens if their cap was not exceeded by the total value. If their valuation cap was exceeded, they were essentially removed from the sale, so their total amount of ETH they contributed to the sale is refunded and available for withdrawal. This avoids costly looping and calculations that were needed in the previous version when bids were sorted and removed/partially removed throughout the sale, cutting down on gas price. Sending ETH is a costly transaction, so removing all the unnecessary ETH transfers is very important. Both versions enforce the monotonically increasing valuation variant discussed in section 5.2 of the technical paper, but this version significantly cuts down on gas costs.
This version also enforces that personal valuation caps can only be submitted in evenly spaced valuations. These are spaced by the 3 most significant digits of each personal valuation cap. These make it so there is even spacing in the linked list struct that holds the personal valuations, meaning the bids are spaced in a more efficient fashion, further saving gas on searching the linked list.
Valuation Cutoff Pointer
To accomplish this, the library utilizes a pointer throughout the sale that indicates which personal valuation cap in the linked list is the cutoff point for being allowed in the sale. It only counts bids towards the total sale valuation that have personal valuation caps that are greater than the total sale valuation. This pointer will be correlated to the total sale valuation, but since it will always point to a submitted personal valuation cap, it will often not be exactly equal to the total sale valuation, but will be relatively close.
At the beginning of the sale, the pointer is set at 0, indicating that the valuation of the sale is 0 and there are no bids that have been submitted or âdiscardedâ from the sale.
The state at the beginning of the sale. The box on the left is the empty linked list representing the sorted submitted personal valuation caps.Bid Process:
(This process is taken from the submitBid function in InteractiveCrowdsaleLib.sol)
Every time a new bid is submitted, its personal valuation cap is added to the sorted linked list of personal valuation caps. Then the contract adds its bid to a sum of all bids submitted with that same personal valuation cap. After that, it records the amount of ETH submitted in that bid and the token price bonus at the time the bid was submitted.
Then, if the personal valuation cap is less than the current total sale valuation, the bid is still registered by the sale, but it is not counted towards the total sale valuation. If the personal valuation cap is greater than the current total sale valuation, then the bid is added to the current valuation and the cutoff pointer is potentially increased to show which bids have been âkicked outâ of the sale. Bids that are overtaken by the pointer are subtracted from the total sale valuation but still remain recorded in case the pointer decreases.
This valuation cutoff pointer mechanism is active throughout the entire sale, but will increase and decrease during the first stage of the sale. After the withdrawal lock, the pointer, like the total sale valuation, is monotonically increasing, meaning that it cannot decrease, only increase or stay the same, since manual withdrawals are not possible in that stage.
If you reference the technical paper, youâll see in Section 4, step 3, part 3 that bids that are equal to the current valuation pointer are refunded a portion of their bids instead of being kicked out to keep the valuation monotonically increasing as bids are removed. This is now only necessary to do once, at the very end of the sale. Bids with personal valuation caps equal to the valuation pointer will be partially refunded ETH and receive the rest of their purchase in tokens. This still satisfies the requirement in section 5.2.
Valuation Pointer Mechanics Walkthrough
Iâll do a quick walkthrough with some diagrams to show the correct pointer movement. Weâll start with the first bid in the sale, Josh sending 9 ETH with a personal valuation cap of 186 ETH. Here is the state after the first bid.
As you can see, Josh has contributed 9 ETH, so the total sale valuation has increased to 9. His personal valuation cap was added to the sorted list of caps, but since the total sale valuation is still less than his cap, the pointer is still pointing at zero, showing that all bids still remain in the sale.
You might be confused that the pointer isnât equal to the current valuation. The reason for this is that the pointer needs to always point at one of the personal valuation caps, indicating which cap is the cutoff to remain in the sale. This is slightly different than what is specified in section 4 of the technical paper, but necessary for proper functionality of the pointer mechanism and ensuring monotonically increasing sale valuation.
A similar state happens when the second bid is submitted with a high personal valuation cap:
Going smoothly so far! Now lets see what happens when a bid is submitted with a personal valuation cap that is less than the total sale valuation:
The bid has a personal valuation cap below the total sale valuation, so it doesnât affect the sale at allPointer is fixed when another bid comes in
As you can see, Robbieâs bid with a personal valuation cap less than the total sale valuation is still recorded in the list and storage, but does not affect the total sale valuation or pointer at all. When another bid comes in, the pointer is moved to 12 to show that personal valuation caps of 12 and lower are not involved in the sale.
Now lets see what happens when a bidders cap is exceeded:
As you can see from the next two bids, the total sale valuation would increase to more than Gusâ cap of 38, but removing his bid would decrease the total sale valuation to below 38. This creates an issue with deciding whether or not he should remain in the sale. The sale accounts for this by moving the pointer to 38, his cap, and setting the total sale valuation to the same number. This indicates that he will get a partial purchase of his tokens when he withdraws his tokens at the end of the sale.
Withdrawals During the First Stage of the Sale
At some point, some of the participants might want to manually withdraw their bid. To protect from blackout attacks (detailed in section 5.3 of the technical paper) contributors that manually withdraw will forfeit part of their early contribution bonus and a portion of their contribution will be locked in to the sale. When a contributor withdraws, they will get a partial refund, the rest will be converted to tokens, minus part of the early contribution bonus. You can read about the reasoning for this choice in section 5.3 of the paper. Please remember, this is only for manual withdrawals before the âwithdrawal lockâ. Automated withdrawals due to personal cap being lower than the total valuation will not be penalized.
Letâs look at how it would affect our example sale.
In this example, JG wants to withdraw his 5 ETH contribution from the sale. The figure shows the state of the sale after the withdrawal.
The penalty increases linearly throughout the first stage of the sale. For simplicityâs sake, we are assuming that the penalty at this point is 40%. JG gets 3 ETH back and the remaining 2 is still committed to the sale. This decreases the total sale valuation to 35, and the pointer stays at 38. If there was a bid with a personal valuation cap of 35, the pointer would be pointing at that, but since there isnât, it stays at 38.
As you can probably imagine, manual withdrawals can lead to a reduction in the Total Valuation and as a result, bids that were previously excluded can once again be included.
For clarification, bids that have been passed by the valuation pointer are still subject to the withdrawal penalty before the withdrawal lock, but not after. You can read the reasoning for this in section 5.3 of the technical paper.
Most of the algorithms for tracking bids require changing only a few values and iterating over a small number of nodes in the linked list. This significantly decreases the potential gas cost compared to the costly operations required for looping through the list, removing nodes, giving bidders with minimal bids partial refunds after each loop, and resetting bidders stored bid history.
Potential Improvements
Buyers currently do not have a way to enforce a minimum valuation:
The goal of the technical paper is to give participants as much control and comfort in participating in the sale at their desired valuation. Some participants might be uncomfortable participating in the sale if the valuation doesnât exceed a certain value. A solution was proposed for this as a possible addition to the core protocol. Similarly to the personal valuation caps, users would also be able to include personal valuation minimums where bids are kicked out of the sale if the total sale valuation doesnât meet their minimum.
We devised an algorithm for this, but eventually came to the conclusion we would hold off on including it in the current implementation. The complexity of the interactions between personal minimums and personal valuation caps would be too challenging to reasonably build and test at this point. Modular cares about building secure systems, so ensuring that the base functionality of the Interactive token sale is functional and secure was our top priority. Instead, we just included a minimum valuation that the team running the crowdsale sets, and participants can decide if they are ok with the minimum valuation before they submit their bids.
We hope to include personal minimums in a future version of the implementation.
Current Status
Developing the protocol implementation is going quite well, as we are reaching the last steps of finishing up the first draft. Weâre currently working on writing as many tests as possible, expanding our coverage and hitting as many possible sale configurations and test cases as we can.
You can get involved in the development of this protocol! The development of the contract is open source and we are always looking for contributors, especially with writing tests for the contracts to account for all possible configurations and test cases. If you want to get involved, you can get on the repo and comment on a current issue or open an issue.
Issues that currently need addressing are:
- 100% Code coverage (triggering all possible throws, conditionals, etc)
- testing all varieties of different sale configurations and participant behaviors to ensure behavior stays consistent throughout every scenario.
- Updating documentation, adding a FAQ, and adding more diagrams to more accurately describe the behavior of the contracts.
You can also contact me at joshua@modular.network and I can help you figure out ways to get involved. Your contribution will be acknowledged and rewarded!
The contracts are also transitioning into a professional security audit to prepare them to be used in a production setting.
Learn More!
This is a crowdsale model that has the potential to make a huge difference in how ICOs are run and projects are valued. If you would like to learn how you can get involved or want to use the Interactive ICO for your token sale, please get in contact with us by signing up for the newsletter and filling out our survey. Youâll be able to get updates about the status of the protocol and the work that is being done on creating a great user experience for it.
Link to IICOÂ website:
IICO Protocol - Interactive Coin Offering
HUGE thanks to C. Brown, Gustavo (Gus) Guimaraes, JG Carvalho, and Rob Bent for their work on building and testing the implementation, and for reading and making suggestions on this post. And thank you especially to Jason Teutsch and Vitalik Buterin for designing this awesome protocol and collaborating with us on improving the protocol, building the implementation, and writing this post!
You can also find out what else we are doing at Modular by checking out our website at https://modular.network. We have some great projects in the works and canât wait to share them with everyone!
Building the Interactive Token Sale was originally published in Modular-Network on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.