DAICOVO In a Nutshell

DAICOVO is an open-sourced library of smart contracts that implements a concept of DAICO. The DAICO is a new ICO model, proposed this January by the one of Ethereum founders Vitalik Buterin. It is a self-regulatory framework to support ICOs while 1) mitigating the risk of investors and 2) preserving a token issuer’s freedom to raise funds.

As I explained in the previous post, there are two important concepts in the DAICO, and accordingly in the DAICOVO. The first is a tap. Token issuers decide how much ETH they can withdraw per a second(tap) upfront, and then, they initiate their ICOs in whatever forms they want: a capped sale, an uncapped sale, or a Dutch auction. A staggered release of the fund prohibits token issuers from running away with their funds. The second is voting. Token holders have two voting rights after the ICO: 1) self-destruction of the smart contract(refund) and 2) the tap raising. If the proposal garners support from a majority, the contract will self-destruct or the tap is raised. The self-destruction of the contract will refund all the money left in the pool to investors. If the tap were raised, token issuers can withdraw more ETH per a second, which is a strong incentive for them to hustle.

Now, I will go over the structure and the operation flow of DAICOVO.

Structure of DAICOVO

DaicovoStandardToken(Token)

This is a template for a token. You can set up parameters such as a token name for each project. It’s ERC20 compatible with some extensions of ERC223. However, the ERC223 part of the code is a bit different from the original interface of the ERC223.

TokenController

This contract is in charge of a token issuance. It is a project owner(the owner of TokenController contract) who has the authority to issue tokens before the sale. During the sale, TokenSaleManager holds that power. As of Jun 29, 2018, no one possesses the power to issue tokens anymore after the sale. However, it will become possible to issue tokens through voting in the upcoming updates. For this reason, we’ve already written the interface that allows the Voting contract to issue tokens through voting after the sale.

TimeLockPool

This contract locks up ETH and tokens for a certain period, and allows project owners to withdraw the fund after that period. A single TimeLockPool contract can store various kinds of ERC20 tokens and ETH.

TokenSaleManager

The TokenSaleManager contract manages a series of token sales. There are some TokenSale contracts under this contract. When ETH is sent to the TokenSale contract, it makes the order to issue tokens to the TokenController via TokenSaleManager contract. Once all the TokenSale contracts are over, it sends a signal to start a project to DaicoPool contract. And all the funds raised through the sale will be sent to the DaicoPool contract.

TokenSale

The TokenSale contract is a template for a token sale. A single TokenSale contract deals with each phase of sales such as a pre-sale or a crowd sale. Furthermore, you can set up parameters such as token price, a term of a sale, the number of tokens on sale, a time lock(true or false), or a carryover(true or false).

DaicoPool

The DaicoPool contract pools the funds raised. Each TokenSale contract sends the funds to this pool contract once it’s finalized. When this contract receives the signal to start a project, the tap will be opened, which allows project owners to withdraw the funds. Furthermore, this contract acts accordingly when it receives the signal to raise a tap or self-destruct the contract from the Voting contract.

Voting

The Voting contract. Anybody can make a proposal by sending a certain amount of ETH to this contract. There are two proposals you can make: the tap-raising and self-destruction. If the proposal garners support from a majority, Voting contract sends the signal to DaicoPool contract.

Operation Flow of DAICOVO

Initial Token Distribution

Deploy the DaicovoStandardToken contract(Assign a token name, a symbol, and the number of decimal places as a parameter).

Deploy the TokenController contract(Assign the Token address you deployed above as an argument).

Change the Owner to the TokenController by executing DaicovoStandardToken.transferOwnership(address newOwner). Now, the TokenController is in charge of issuing tokens.

Deploy the TimeLockPool contract.

Project owners distribute tokens through the TokenController(They can distribute the tokens that will be allocated to their team members or marketing expenses).

*The project owner won’t be able to distribute tokens anymore once the sale starts.

Before a Token Sale

Deploy the DaicoPool contract(Assign Token, the initial tap, and the initial funds as a parameter.). Voting will be automatically deployed in the constructor of the DaicoPool contract.

Deploy the TokenSaleManager contract(Assign Token, TimeLockPool and DaicoPool as a parameter.).

Set up the token sale in TokenSaleManager.addTokenSale(…). Assign parameters of a token sale such as token price, a term of a sale, the number of tokens on sale, a time lock(true or false), or a carryover(true or false).

Once you set up all the necessary sales, execute Initialize() in the TokenSaleManager(The settings of the token sales will be fixed at this point).

Execute OpenTokenSale in TokenController and give TokenSaleManager as a parameter. The project owner won’t be able to distribute tokens anymore.

*Investors can make sure that project owners keep the promise of their distribution written on their white paper as everybody can see the actual distribution before the sale.

Project owners execute TokenSaleManager.addToWhitelist(or addManyToWhitelist) to add addresses that was KYC’d already. Only these addresses can participate in the sale(You can add addresses to this whitelist later).

*We have designed the contract in a way that all the processes after the token sale will progress trustlessly: even project owners cannot change the content of the sale or shut down the operation. The token sale will start in such a way that all the processes are clear to everybody.

During a Token Sale

The sale will be open when the time you set up in the first TokenSale comes.

Whitelisted investors can receive tokens by sending ETH to the TokenSale contract. The TokenSale contract specifies the minimum price for token purchase, and a transaction will fail if your purchase were below that.

When the sale period ends or all the tokens are sold, you can finalize the TokenSale with TokenSaleManager.finalize(uint256 index). Everyone can execute this finalize operation.

*The funds raised will be sent to the DaicoPool contract once it’s finalized(You can finalize as many times you want in case the funds is left in the TokenSale for some reasons.). On top of that, the TokenSale will be initialized when the DaicoPool is finalized. If you set up the carryover to true in the TokenSale, it will operate a carryover, and unsold tokens will be taken over by the next TokenSale.

When all the TokenSale contracts are finalized, you can execute TokenSaleManager.finalizeTokenSaleManager(). Again, anyone can finalize this operation. The finalize function in the TokenSaleManager will open the tap in the DaicoPool, which releases the initial funds and the funds according to the tap. Furthermore, token holders can make proposals at this point.

After a Token Sale

The project owner can withdraw the funds in the DaicoPool contract once the DaicoPool starts.

Again, token holders can make proposals, and once somebody makes a proposal, it makes a transition to a voting mode.

Voting Mode

*DaicoPool behaves in the same way during a voting mode.

Token holders can make a proposal to 1) raise the tap(Voting.addRaiseTapProposal(…)) or 2) self-destruct the contract (Self Destruction (Voting.addDestructionProposal(…)) by paying a certain amount of ETH.

After the proposal is made, 14-day voting period starts immediately. Token holders can vote for the proposal by depositing their tokens to the Voting contract(Voting.vote(bool agree, uint256 amount)).

When the voting period ends, anyone can finalize the Voting. If it has enough support to pass, it sends the RaiseTap or SelfDestruction signal to the DaicoPool. If it doesn’t have enough support to pass, nothing happens.

Once it’s finalized, voters can withdraw tokens they have deposited. To be more specific, they can execute returnToken() to the Voting. Everyone can execute this function, and tokens will be returned to original token holders regardless of the executioner of the function.

*In our project, we will write the script to trigger the return of tokens automatically so that voters don’t have to take initiative to take their tokens back.

Self-destruction of the Contract

If the proposal of a self-destruction garners support from a majority, the DaicoPool contract immediately turns off the tap after it releases the fund of 30 days to a project owner. This fund is released to allow project owners to pay expenses for a month. Once the tap is turned off, token holders can take back their money.

More precisely, they can receive money from the funds left in exchange with their tokens by running DaicoPool.refund(…). You can calculate the money you will receive with the equation below.

The funds left in DaicoPool * tokens you exchange / total supply