Decentralized investments

First DAICO iteration has ended and will serve as proof of concept.

Since softcap wasn't reached, personal Funding Vaults have been unlocked and

you can follow the tutorial on the CashBack page to retrieve your investment.

Thank you for your support.

What is BlockBits?

BlockBits DApp is not just another crowdfunding platform, it’s the innovation that sets the standard of what the ICO market urgently needs to become: safe investments and legitimate projects. For the first time investors can decide if they keep backing a project or take their money back.

The platform provides innovative mechanisms such as safe funding vaults and secure milestone based payments and is designed to become fully independent, maintained and governed by its token holders. Blockbits is launched through the very code submitted here as MVP.

Welcome to the smart company of the future! Never tired, no bias just code, autonomous platform distributed throughout the blockchain, mutable only with its community approval, always ready for the innovative ideas of tomorrow!

Open Source

Everything is provided under the MIT License unless stated otherwise.

Code View

/*

 * @name        Application Entity Contract
 * @package     BlockBitsIO
 * @author      Micky Socaci

 Contains the main company Entity Contract code deployed and linked to the Gateway Interface.

*/

pragma solidity ^0.4.17;

import "./GatewayInterface.sol";
import "./Entity/Proposals.sol";
import "./Entity/Funding.sol";
import "./Entity/Meetings.sol";
import "./Entity/Milestones.sol";
import "./Entity/BountyManager.sol";
import "./Entity/TokenManager.sol";
import "./Entity/FundingManager.sol";
import "./Entity/ListingContract.sol";
import "./Entity/NewsContract.sol";

contract ApplicationEntity {

    /* Source Code Url */
    bytes32 sourceCodeUrl;

    /* Entity initialised or not */
    bool public _initialized = false;

    /* Entity locked or not */
    bool public _locked = false;

    /* Current Entity State */
    uint8 public CurrentEntityState;

    /* Available Entity State */
    mapping (bytes32 => uint8) public EntityStates;

    /* GatewayInterface address */
    address public GatewayInterfaceAddress;

    /* Parent Entity Instance */
    GatewayInterface GatewayInterfaceEntity;

    /* Asset Entities */
    Proposals public ProposalsEntity;
    Funding public FundingEntity;
    Milestones public MilestonesEntity;
    Meetings public MeetingsEntity;
    BountyManager public BountyManagerEntity;
    TokenManager public TokenManagerEntity;
    ListingContract public ListingContractEntity;
    FundingManager public FundingManagerEntity;
    NewsContract public NewsContractEntity;

    /* Asset Collection */
    mapping (bytes32 => address) public AssetCollection;
    mapping (uint8 => bytes32) public AssetCollectionIdToName;
    uint8 public AssetCollectionNum = 0;

    event EventAppEntityReady ( address indexed _address );
    event EventAppEntityCodeUpgradeProposal ( address indexed _address, bytes32 indexed _sourceCodeUrl );
    event EventAppEntityInitAsset ( bytes32 indexed _name, address indexed _address );
    event EventAppEntityInitAssetsToThis ( uint8 indexed _assetNum );
    event EventAppEntityAssetsToNewApplication ( address indexed _address );
    event EventAppEntityLocked ( address indexed _address );

    address public deployerAddress;

    function ApplicationEntity() public {
        deployerAddress = msg.sender;
        setEntityStates();
        CurrentEntityState = getEntityState("NEW");
    }

    function setEntityStates() internal {

        // ApplicationEntity States
        EntityStates["__IGNORED__"]                 = 0;
        EntityStates["NEW"]                         = 1;
        EntityStates["WAITING"]                     = 2;
        EntityStates["IN_FUNDING"]                  = 3;
        EntityStates["IN_DEVELOPMENT"]              = 5;
        EntityStates["IN_CODE_UPGRADE"]             = 50;
        EntityStates["UPGRADED"]                    = 100;
        EntityStates["IN_GLOBAL_CASHBACK"]          = 150;
        EntityStates["LOCKED"]                      = 200;
        EntityStates["DEVELOPMENT_COMPLETE"]        = 250;
    }

    function getEntityState(bytes32 name) public view returns (uint8) {
        return EntityStates[name];
    }

    /*
    * Initialize Application and it's assets
    * If gateway is freshly deployed, just link
    * else, create a voting proposal that needs to be accepted for the linking
    *
    * @param        address _newAddress
    * @param        bytes32 _sourceCodeUrl
    *
    * @modifiers    requireNoParent, requireNotInitialised
    */
    function linkToGateway(
        address _GatewayInterfaceAddress,
        bytes32 _sourceCodeUrl
    )
        external
        requireNoParent
        requireNotInitialised
        onlyDeployer
    {
        GatewayInterfaceAddress = _GatewayInterfaceAddress;
        sourceCodeUrl = _sourceCodeUrl;

        // init gateway entity and set app address
        GatewayInterfaceEntity = GatewayInterface(GatewayInterfaceAddress);
        GatewayInterfaceEntity.requestCodeUpgrade( address(this), sourceCodeUrl );
    }

    function setUpgradeState(uint8 state) public onlyGatewayInterface {
        CurrentEntityState = state;
    }

    /*
        For the sake of simplicity, and solidity warnings about "unknown gas usage" do this.. instead of sending
        an array of addresses
    */
    function addAssetProposals(address _assetAddresses) external requireNotInitialised onlyDeployer {
        ProposalsEntity = Proposals(_assetAddresses);
        assetInitialized("Proposals", _assetAddresses);
    }

    function addAssetFunding(address _assetAddresses) external requireNotInitialised onlyDeployer {
        FundingEntity = Funding(_assetAddresses);
        assetInitialized("Funding", _assetAddresses);
    }

    function addAssetMilestones(address _assetAddresses) external requireNotInitialised onlyDeployer {
        MilestonesEntity = Milestones(_assetAddresses);
        assetInitialized("Milestones", _assetAddresses);
    }

    function addAssetMeetings(address _assetAddresses) external requireNotInitialised onlyDeployer {
        MeetingsEntity = Meetings(_assetAddresses);
        assetInitialized("Meetings", _assetAddresses);
    }

    function addAssetBountyManager(address _assetAddresses) external requireNotInitialised onlyDeployer {
        BountyManagerEntity = BountyManager(_assetAddresses);
        assetInitialized("BountyManager", _assetAddresses);
    }

    function addAssetTokenManager(address _assetAddresses) external requireNotInitialised onlyDeployer {
        TokenManagerEntity = TokenManager(_assetAddresses);
        assetInitialized("TokenManager", _assetAddresses);
    }

    function addAssetFundingManager(address _assetAddresses) external requireNotInitialised onlyDeployer {
        FundingManagerEntity = FundingManager(_assetAddresses);
        assetInitialized("FundingManager", _assetAddresses);
    }

    function addAssetListingContract(address _assetAddresses) external requireNotInitialised onlyDeployer {
        ListingContractEntity = ListingContract(_assetAddresses);
        assetInitialized("ListingContract", _assetAddresses);
    }

    function addAssetNewsContract(address _assetAddresses) external requireNotInitialised onlyDeployer {
        NewsContractEntity = NewsContract(_assetAddresses);
        assetInitialized("NewsContract", _assetAddresses);
    }

    function assetInitialized(bytes32 name, address _assetAddresses) internal {
        if(AssetCollection[name] == 0x0) {
            AssetCollectionIdToName[AssetCollectionNum] = name;
            AssetCollection[name] = _assetAddresses;
            AssetCollectionNum++;
        } else {
            // just replace
            AssetCollection[name] = _assetAddresses;
        }
        EventAppEntityInitAsset(name, _assetAddresses);
    }

    function getAssetAddressByName(bytes32 _name) public view returns (address) {
        return AssetCollection[_name];
    }

    /* Application Bylaws mapping */
    mapping (bytes32 => uint256) public BylawsUint256;
    mapping (bytes32 => bytes32) public BylawsBytes32;


    function setBylawUint256(bytes32 name, uint256 value) public requireNotInitialised onlyDeployer {
        BylawsUint256[name] = value;
    }

    function getBylawUint256(bytes32 name) public view requireInitialised returns (uint256) {
        return BylawsUint256[name];
    }

    function setBylawBytes32(bytes32 name, bytes32 value) public requireNotInitialised onlyDeployer {
        BylawsBytes32[name] = value;
    }

    function getBylawBytes32(bytes32 name) public view requireInitialised returns (bytes32) {
        return BylawsBytes32[name];
    }

    function initialize() external requireNotInitialised onlyGatewayInterface returns (bool) {
        _initialized = true;
        EventAppEntityReady( address(this) );
        return true;
    }

    function getParentAddress() external view returns(address) {
        return GatewayInterfaceAddress;
    }

    function createCodeUpgradeProposal(
        address _newAddress,
        bytes32 _sourceCodeUrl
    )
        external
        requireInitialised
        onlyGatewayInterface
        returns (uint256)
    {
        // proposals create new.. code upgrade proposal
        EventAppEntityCodeUpgradeProposal ( _newAddress, _sourceCodeUrl );

        // return true;
        return ProposalsEntity.addCodeUpgradeProposal(_newAddress, _sourceCodeUrl);
    }

    /*
    * Only a proposal can update the ApplicationEntity Contract address
    *
    * @param        address _newAddress
    * @modifiers    onlyProposalsAsset
    */
    function acceptCodeUpgradeProposal(address _newAddress) external onlyProposalsAsset  {
        GatewayInterfaceEntity.approveCodeUpgrade( _newAddress );
    }

    function initializeAssetsToThisApplication() external onlyGatewayInterface returns (bool) {

        for(uint8 i = 0; i < AssetCollectionNum; i++ ) {
            bytes32 _name = AssetCollectionIdToName[i];
            address current = AssetCollection[_name];
            if(current != address(0x0)) {
                if(!current.call(bytes4(keccak256("setInitialOwnerAndName(bytes32)")), _name) ) {
                    revert();
                }
            } else {
                revert();
            }
        }
        EventAppEntityInitAssetsToThis( AssetCollectionNum );

        return true;
    }

    function transferAssetsToNewApplication(address _newAddress) external onlyGatewayInterface returns (bool){
        for(uint8 i = 0; i < AssetCollectionNum; i++ ) {

            bytes32 _name = AssetCollectionIdToName[i];
            address current = AssetCollection[_name];
            if(current != address(0x0)) {
                if(!current.call(bytes4(keccak256("transferToNewOwner(address)")), _newAddress) ) {
                    revert();
                }
            } else {
                revert();
            }
        }
        EventAppEntityAssetsToNewApplication ( _newAddress );
        return true;
    }

    /*
    * Only the gateway interface can lock current app after a successful code upgrade proposal
    *
    * @modifiers    onlyGatewayInterface
    */
    function lock() external onlyGatewayInterface returns (bool) {
        _locked = true;
        CurrentEntityState = getEntityState("UPGRADED");
        EventAppEntityLocked(address(this));
        return true;
    }

    /*
        DUMMY METHOD, to be replaced in a future Code Upgrade with a check to determine if sender should be able to initiate a code upgrade
        specifically used after milestone development completes
    */
    address testAddressAllowUpgradeFrom;
    function canInitiateCodeUpgrade(address _sender) public view returns(bool) {
        // suppress warning
        if(testAddressAllowUpgradeFrom != 0x0 && testAddressAllowUpgradeFrom == _sender) {
            return true;
        }
        return false;
    }

    /*
    * Throws if called by any other entity except GatewayInterface
    */
    modifier onlyGatewayInterface() {
        require(GatewayInterfaceAddress != address(0) && msg.sender == GatewayInterfaceAddress);
        _;
    }

    /*
    * Throws if called by any other entity except Proposals Asset Contract
    */
    modifier onlyProposalsAsset() {
        require(msg.sender == address(ProposalsEntity));
        _;
    }

    modifier requireNoParent() {
        require(GatewayInterfaceAddress == address(0x0));
        _;
    }

    modifier requireNotInitialised() {
        require(_initialized == false && _locked == false);
        _;
    }

    modifier requireInitialised() {
        require(_initialized == true && _locked == false);
        _;
    }

    modifier onlyDeployer() {
        require(msg.sender == deployerAddress);
        _;
    }

    event DebugApplicationRequiredChanges( uint8 indexed _current, uint8 indexed _required );
    event EventApplicationEntityProcessor(uint8 indexed _current, uint8 indexed _required);

    function doStateChanges() public {

        if(!_locked) {
            // process assets first so we can initialize them from NEW to WAITING
            AssetProcessor();

            var (returnedCurrentEntityState, EntityStateRequired) = getRequiredStateChanges();
            bool callAgain = false;

            DebugApplicationRequiredChanges( returnedCurrentEntityState, EntityStateRequired );

            if(EntityStateRequired != getEntityState("__IGNORED__") ) {
                EntityProcessor(EntityStateRequired);
                callAgain = true;
            }
        } else {
            revert();
        }
    }

    function hasRequiredStateChanges() public view returns (bool) {
        bool hasChanges = false;
        if(!_locked) {
            var (returnedCurrentEntityState, EntityStateRequired) = getRequiredStateChanges();
            // suppress unused local variable warning
            returnedCurrentEntityState = 0;
            if(EntityStateRequired != getEntityState("__IGNORED__") ) {
                hasChanges = true;
            }

            if(anyAssetHasChanges()) {
                hasChanges = true;
            }
        }
        return hasChanges;
    }

    function anyAssetHasChanges() public view returns (bool) {
        if( FundingEntity.hasRequiredStateChanges() ) {
            return true;
        }
        if( FundingManagerEntity.hasRequiredStateChanges() ) {
            return true;
        }
        if( MilestonesEntity.hasRequiredStateChanges() ) {
            return true;
        }
        if( ProposalsEntity.hasRequiredStateChanges() ) {
            return true;
        }

        return extendedAnyAssetHasChanges();
    }

    // use this when extending "has changes"
    function extendedAnyAssetHasChanges() internal view returns (bool) {
        if(_initialized) {}
        return false;
    }

    // use this when extending "asset state processor"
    function extendedAssetProcessor() internal  {
        // does not exist, but we check anyway to bypass compier warning about function state mutability
        if ( CurrentEntityState == 255 ) {
            ProposalsEntity.process();
        }
    }

    // view methods decide if changes are to be made
    // in case of tasks, we do them in the Processors.

    function AssetProcessor() internal {


        if ( CurrentEntityState == getEntityState("NEW") ) {

            // move all assets that have states to "WAITING"
            if(FundingEntity.hasRequiredStateChanges()) {
                FundingEntity.doStateChanges();
            }

            if(FundingManagerEntity.hasRequiredStateChanges()) {
                FundingManagerEntity.doStateChanges();
            }

            if( MilestonesEntity.hasRequiredStateChanges() ) {
                MilestonesEntity.doStateChanges();
            }

        } else if ( CurrentEntityState == getEntityState("WAITING") ) {

            if( FundingEntity.hasRequiredStateChanges() ) {
                FundingEntity.doStateChanges();
            }
        }
        else if ( CurrentEntityState == getEntityState("IN_FUNDING") ) {

            if( FundingEntity.hasRequiredStateChanges() ) {
                FundingEntity.doStateChanges();
            }

            if( FundingManagerEntity.hasRequiredStateChanges() ) {
                FundingManagerEntity.doStateChanges();
            }
        }
        else if ( CurrentEntityState == getEntityState("IN_DEVELOPMENT") ) {

            if( FundingManagerEntity.hasRequiredStateChanges() ) {
                FundingManagerEntity.doStateChanges();
            }

            if(MilestonesEntity.hasRequiredStateChanges()) {
                MilestonesEntity.doStateChanges();
            }

            if(ProposalsEntity.hasRequiredStateChanges()) {
                ProposalsEntity.process();
            }
        }
        else if ( CurrentEntityState == getEntityState("DEVELOPMENT_COMPLETE") ) {

            if(ProposalsEntity.hasRequiredStateChanges()) {
                ProposalsEntity.process();
            }
        }

        extendedAssetProcessor();
    }

    function EntityProcessor(uint8 EntityStateRequired) internal {

        EventApplicationEntityProcessor( CurrentEntityState, EntityStateRequired );

        // Update our Entity State
        CurrentEntityState = EntityStateRequired;

        // Do State Specific Updates

        if ( EntityStateRequired == getEntityState("IN_FUNDING") ) {
            // run Funding state changer
            // doStateChanges
        }

    }

    /*
     * Method: Get Entity Required State Changes
     *
     * @access       public
     * @type         method
     *
     * @return       ( uint8 CurrentEntityState, uint8 EntityStateRequired )
     */
    function getRequiredStateChanges() public view returns (uint8, uint8) {

        uint8 EntityStateRequired = getEntityState("__IGNORED__");

        if( CurrentEntityState == getEntityState("NEW") ) {
            // general so we know we initialized
            EntityStateRequired = getEntityState("WAITING");

        } else if ( CurrentEntityState == getEntityState("WAITING") ) {

            // Funding Started
            if( FundingEntity.CurrentEntityState() == FundingEntity.getEntityState("IN_PROGRESS") ) {
                EntityStateRequired = getEntityState("IN_FUNDING");
            }

        } else if ( CurrentEntityState == getEntityState("IN_FUNDING") ) {

            if(FundingEntity.CurrentEntityState() == FundingEntity.getEntityState("SUCCESSFUL_FINAL")) {
                // SUCCESSFUL_FINAL means FUNDING was successful, and FundingManager has finished distributing tokens and ether
                EntityStateRequired = getEntityState("IN_DEVELOPMENT");

            } else if(FundingEntity.CurrentEntityState() == FundingEntity.getEntityState("FAILED_FINAL")) {
                // Funding failed..
                EntityStateRequired = getEntityState("IN_GLOBAL_CASHBACK");
            }

        } else if ( CurrentEntityState == getEntityState("IN_DEVELOPMENT") ) {

            if(MilestonesEntity.CurrentEntityState() == MilestonesEntity.getEntityState("DEVELOPMENT_COMPLETE")) {
                // check if we finished developing all milestones .. and if so move state to complete.
                EntityStateRequired = getEntityState("DEVELOPMENT_COMPLETE");
            }

            if(MilestonesEntity.CurrentEntityState() == MilestonesEntity.getEntityState("DEADLINE_MEETING_TIME_FAILED")) {
                EntityStateRequired = getEntityState("IN_GLOBAL_CASHBACK");
            }

        }

        return (CurrentEntityState, EntityStateRequired);
    }

    function getTimestamp() view public returns (uint256) {
        return now;
    }

                        
                    
Test Runner
[ Click contents to pause / resume ]
npm run test Starting our own testrpc instance at port 8545 Using network 'rpc'. Compiling ./contracts/Algorithms/TokenSCADA1Market.sol...
Compiling ./contracts/Algorithms/TokenSCADAGeneric.sol...
Compiling ./contracts/ApplicationAsset.sol...
Compiling ./contracts/ApplicationEntity.sol...
Compiling ./contracts/ApplicationEntityABI.sol...
Compiling ./contracts/ApplicationEntitySecond.sol...
Compiling ./contracts/Entity/BountyManager.sol...
Compiling ./contracts/Entity/Funding.sol...
Compiling ./contracts/Entity/FundingManager.sol...
Compiling ./contracts/Entity/FundingVault.sol...
Compiling ./contracts/Entity/ListingContract.sol...
Compiling ./contracts/Entity/Meetings.sol...
Compiling ./contracts/Entity/Milestones.sol...
Compiling ./contracts/Entity/NewsContract.sol...
Compiling ./contracts/Entity/Proposals.sol...
Compiling ./contracts/Entity/Token.sol...
Compiling ./contracts/Entity/TokenManager.sol...
Compiling ./contracts/Entity/UpgradeTestAsset.sol...
Compiling ./contracts/GatewayInterface.sol...
Compiling ./contracts/Inputs/FundingInputDirect.sol...
Compiling ./contracts/Inputs/FundingInputGeneral.sol...
Compiling ./contracts/Inputs/FundingInputMilestone.sol...
Compiling ./contracts/zeppelin/math/SafeMath.sol...
Compiling ./contracts/zeppelin/token/BasicToken.sol...
Compiling ./contracts/zeppelin/token/ERC20.sol...
Compiling ./contracts/zeppelin/token/ERC20Basic.sol...
Compiling ./contracts/zeppelin/token/StandardToken.sol...
Compiling ./test/helpers/ExecutionTarget.sol...
Compiling ./test/helpers/SolidityAccountUtils.sol...
Compiling ./test/mocks/EmptyStub.sol...
Compiling ./test/mocks/GenericCaller.sol...
Compiling ./test/mocks/SafeMathMock.sol...
Compiling ./test/mocks/SampleRecipientSuccess.sol...
Compiling ./test/mocks/SampleRecipientThrow.sol...
Compiling ./test/mocks/TestApplicationAsset.sol...
Compiling ./test/mocks/TestApplicationEntity.sol...
Compiling ./test/mocks/TestApplicationEntityABI.sol...
Compiling ./test/mocks/TestApplicationEntityBad.sol...
Compiling ./test/mocks/TestApplicationEntitySecond.sol...
Compiling ./test/mocks/TestBountyManager.sol...
Compiling ./test/mocks/TestERC20Caller.sol...
Compiling ./test/mocks/TestFunding.sol...
Compiling ./test/mocks/TestFundingInputMock.sol...
Compiling ./test/mocks/TestFundingManager.sol...
Compiling ./test/mocks/TestFundingVault.sol...
Compiling ./test/mocks/TestGatewayInterface.sol...
Compiling ./test/mocks/TestListingContract.sol...
Compiling ./test/mocks/TestMeetings.sol...
Compiling ./test/mocks/TestMilestones.sol...
Compiling ./test/mocks/TestNewsContract.sol...
Compiling ./test/mocks/TestProposals.sol...
Compiling ./test/mocks/TestToken.sol...
Compiling ./test/mocks/TestTokenManager.sol...
Compiling ./test/mocks/TestTokenSCADA1Market.sol...
Compiling ./test/mocks/TestUpgradeTestAsset.sol..
----------------------------------------------------------------   Running test collections [28]. ----------------------------------------------------------------   Contract: SafeMath     ✓ multiplies correctly (68ms)     ✓ adds correctly (46ms)     ✓ subtracts correctly (45ms)     ✓ should throw an error if subtraction result would be negative     ✓ should throw an error on addition overflow     ✓ should throw an error on multiplication overflow   Contract: ERC20 Token     ✓ creation: in contract settings should match constructor parameters (175ms)     ✓ creation: should create a correct initial balance for the creator     ✓ creation: test correct setting of vanity information (89ms)     ✓ creation: should succeed in creating over 2^256 - 1 (max) tokens (76ms)     ✓ transfers: ether transfer should be reversed.     ✓ transfers: should transfer 10000 to accounts[1] with accounts[0] having 10000 (46ms)     ✓ transfers: should fail when trying to transfer total amount +1 to accounts[1] with accounts[0] having total amount (56ms)     ✓ transfers: should handle zero-transfers normally (46ms)     ✓ transfers: should throw if receiver address is 0x0     ✓ transferFrom: should throw if receiver address is 0x0 (44ms)     ✓ approvals: msg.sender should approve 100 to accounts[1] (50ms)     ✓ approvals: msg.sender approves accounts[1] of 100 & withdraws 20 once. (214ms)     ✓ approvals: msg.sender approves accounts[1] of 100 & withdraws 20 twice. (207ms)     ✓ approvals: msg.sender approves accounts[1] of 100 & withdraws 50 & 60 (2nd tx should fail) (202ms)     ✓ approvals: attempt withdrawal from account with no allowance (should fail) (45ms)     ✓ approvals: allow accounts[1] 100 to withdraw from accounts[0]. Withdraw 60 and then approve 0 & attempt transfer. (69ms)     ✓ approvals: approve max (2^256 - 1) (44ms)     ✓ approvals: msg.sender approves accounts[1] of max (2^256 - 1) & withdraws 20 (147ms)     ✓ allowance: should start with zero     ✓ allowance: should increase by 50 then decrease by 10 (100ms)     ✓ allowance: should be set to zero if decrease value is higher than existing (61ms)     ✓ events: should fire Transfer event properly     ✓ events: should fire Transfer event normally on a zero transfer     ✓ events: should fire Approval event properly   Contract: Gateway Interface     ✓ initializes with empty properties     requestCodeUpgrade()      throws if address is empty ( 0x0 )      throws if calling object misses the initialize() method      throws if current Application cannot initialize Assets properly (73ms)      links Application if valid (57ms)      creates "Upgrade Proposal" if a previous Application is already linked (325ms)     approveCodeUpgrade()      throws if sender is not current Application      works if sender is current Application (254ms)      throws if current Application cannot transfer assets to new application (191ms)      throws if current Application cannot initialize new application (322ms)      throws if current Application cannot lock itself after transferring assets (308ms)       misc for extra coverage        getNewsContractAddress returns actual linked NewsContract Asset address        getListingContractAddress returns actual linked ListingContract Asset address   Contract: Application Assets     setInitialOwnerAndName()      works if linking an asset for the first time (63ms)      throws if already owned     applyAndLockSettings()      works if called by deployer account and asset is not locked already (65ms)      throws if called before initialization      throws if called when settings are already applied (49ms)      throws if not called by deployer's account     getApplicationAssetAddressByName()      works if asset is initialized and owned by an application (66ms)      works if asset has settings and they are applied (99ms)      throws if asset name does not exist in the app's mapping (63ms)     transferToNewOwner()      works if current caller is owner and requested address is not 0x0 (88ms)      throws if called when internal owner address is invalid      throws if owned and called by other address      throws if new address is 0x0     Application Bylaws in Application Asset      getAppBylawBytes32 returns correct value set by project settings (47ms)      getAppBylawUint256 returns correct value set by project settings (50ms)   Contract: Application Entity     ✓ initializes with empty properties (42ms)     ✓ initializes with deployer address properly (66ms)     setBylawBytes32()      sets and returns a bylaw bytes32 if not initialized (141ms)      throws if if application is already initialized (73ms)     getBylawBytes32()      throws if application is not initialized      returns correct value set by setBylawBytes32 if application is initialized (83ms)     setBylawUint256()      sets and returns a bylaw uint256 if not initialized (132ms)      throws if if application is already initialized (66ms)     application bylaws validation      sets and returns all string and uint256 bylaws (931ms)     getBylawUint256()      throws if application is not initialized      returns correct value set by setBylaw if application is initialized (79ms)     initialize()      throws if called when already initialized (47ms)      throws if called with owner missing ( gateway )      works if owner is set, and it's the one calling (57ms)     initializeAssetsToThisApplication()      throws if not an asset (74ms)      throws if any asset has a 0x0 address (52ms)      throws if caller is not gateway     acceptCodeUpgradeProposal()      throws if caller is not Proposals Asset (72ms)     lock()      throws if sender is not gateway      works if sender is gateway (59ms)     linkToGateway()      throws if called when owner already exists      throws if called when already initialized      will emit EventAppEntityReady on initial linking (38ms)      will emit EventNewProposalCreated if a previous ApplicationEntity is already linked (269ms)     addAsset[AssetName]()      throws if called when already initialized (62ms)      throws if called by any other address than initial deployer (44ms)      linking an asset will emit EventAppEntityInitAsset event (51ms)      linking all assets will emit the same number of EventAppEntityInitAsset events (311ms)      linking an asset, then linking the same asset again, will replace it in mapping (150ms)   Contract: Application Entity Second     initializeNewAssetToThisApplication()      throws if not an asset (97ms)      throws if name does not match the asset (78ms)      throws if caller is not the deployer (54ms)      works if caller is the deployer, and asset was already added (66ms)   Contract: Gateway and Application Integration     ✓ initial deployment (74ms)     ✓ first linking (104ms)     Application upgrades      first upgrade (297ms)      second upgrade (635ms)      throws if an upgrade request is received from an account that does not pass validCodeUpgradeInitiator check (85ms)      mock: works if an upgrade request is received and current ApplicationEntity canInitiateCodeUpgrade allows it (192ms)   Contract: TokenManager Asset     addTokenSettingsAndInit()      properly sets up the tokens if initialized (78ms)      properly sets up the Token SCADA (92ms)     getTokenSCADARequiresHardCap()      returns boolean value stored in SCADA Contract (69ms)   Contract: ListingContract Asset     setManagerAddress()      throws if caller is not deployer      works if caller is applicationEntity (60ms)     addItem()      throws if addItem caller is not applicationEntity      works if caller is applicationEntity (110ms)      works if caller is manager address (119ms)     getNewsContractAddress()      throws if the child does not actually exist      throws if the child itemAddress is invalid (96ms)      returns a news contract address if the child is an actual ApplicationEntity (491ms)     delistChild()      throws if called by any address other than Proposals Asset (39ms)      works if called by proposals asset, resulting in a child with status == false (91ms)   Contract: NewsContract Asset     addItem()      throws if called by anyone else but the deployer address      works if called by deployer address (75ms)     addInternalMessage()      throws if called by anyone else but the Application address      works if called by Application address (59ms)   Contract: Funding Vault     ✓ initializes with empty properties (86ms)     ✓ addPayment throws if not initialized     initialize()      throws if called when already initialized      works if settings are correct and has not been initialized before (125ms)     addPayment()      FUNDING_DIRECT_METHOD - works with correct settings and caller (155ms)      FUNDING_MILESTONE_METHOD - works with correct settings and caller (156ms)      throws if msg.value is missing      throws if payment method does not exist      throws if called by other address than manager (funding contract)      handles multiple payments, irregardless of funding method provided (62ms)   Contract: Bounty Manager     ✓ token balance matches bylaws     Before Funding ended      throws if sendBounty is called (60ms)     After Funding ended      throws if sendBounty is called by anyone else but deployer (55ms)      throws if sendBounty amount is higher than remaining value (45ms)      works if sendBounty is called by deployer and value is lower than remaining (43ms)   Contract: Funding Asset     ✓ deploys with no Funding Stages     ✓ deploys with no multiSigOutputAddress     ✓ deploys with no Funding Inputs (91ms)     ✓ has Funding Inputs once initialized (41ms)     addSettings()      throws if called when settings are locked (54ms)      throws if global soft cap is greater than global hard cap      properly sets up the funding settings (87ms)     first funding stage      successfully creates a funding stage with proper settings (54ms)      throws if end time is before or equal to start time      throws if token selling percentage is higher than 100%       SCADA Disallows Record Hard Cap, Requires Globals        throws if soft cap exists (44ms)        throws if hard cap exists        works if hard cap and soft cap is 0 (57ms)       when at least 1 funding stage already exists        successfully creates the second funding stage with proper settings (55ms)        throws if new funding stage start time overlaps existing stage        throws if new funding stage + existing stage sell more than 100% of tokens     funding stages added, asset initialized      has correct Funding Inputs after ApplicationEntity grabs asset ownership and initializes it       receivePayment()        throws if called directly in the Funding contract        throws if caller is not funding asset        throws if _payment_method is not allowed (75ms)       canAcceptPayment()        returns false if CurrentEntityState is not IN_PROGRESS         CurrentEntityState is IN_PROGRESS          returns false if ETH value is 0          returns false if ETH value is smaller than minimum entry (316ms)          returns false if any State changes are required (359ms)       Funding State: IN_PROGRESS         Funding Input: All          has correct FundingAssetAddress          throws if msg.value is missing          throws if FundingAssetAddress is not set (51ms)          throws if FundingAsset is not pointing to a Contract           Funding Input: Direct            has correct type id = 1           ↓ Direct Payment: GAS USAGE: 2481748            accepts payments using fallback () method and stores in valut's direct pool (197ms)           ↓ First Direct Payment: GAS USAGE: 2481748           ↓ Second Direct Payment: GAS USAGE: 209805            accepts second payment from same investor (272ms)            accepts second payment from same investor using both payment methods ( Direct & Milestone ) (280ms)           Funding Input: Milestone            has correct type id = 2           ↓ Milestone Payment: GAS USAGE: 2481797            accepts payments using fallback () method and stores in valut's milestone pool (198ms)   Contract: Funding Asset - States     ✓ starts with state as New and requires a change to WAITING if current time is before any funding stage (211ms)     ✓ handles ENTITY state change from NEW to WAITING when funding does not start yet (494ms)     ✓ starts with state as New and has correct Token Balance once in WAITING state (427ms)     ✓ handles ENTITY state change from NEW or WAITING to IN_PROGRESS when funding time start has passed (339ms)     ✓ is in IN_PROGRESS, receives payments, pre_ico time passes, should Require change to COOLDOWN (609ms)     ✓ handles ENTITY state change from IN_PROGRESS to COOLDOWN when funding period time start has passed (619ms)     ✓ is in COOLDOWN, ico start time passes, should Require change to IN_PROGRESS (705ms)     ✓ handles ENTITY state change from COOLDOWN to IN_PROGRESS when next funding period time start has passed (795ms)     ✓ is IN_PROGRESS, ico end time passes, should Require change to FUNDING_ENDED (935ms)     handles ENTITY state change from IN_PROGRESS when last funding period time end has passed      to FAILED when payments did not reach soft cap (1033ms)      to SUCCESSFUL when payments reached soft cap (972ms)     handles ENTITY state change from IN_PROGRESS when Hard Cap is Reached      to SUCCESSFUL when payments reached hard cap in first funding stage (pre-ico) (1737ms)      to SUCCESSFUL when payments reached hard cap in last funding stage (ico) (1597ms)     FundingManager Tasks      handles ENTITY state change from FAILED to FAILED_FINAL after FundingManager Task Process finished (2595ms)      handles ENTITY state change from SUCCESSFUL to SUCCESSFUL_FINAL after FundingManager Task Process finished (8163ms)     misc for extra coverage      isFundingStageUpdateAllowed returns false if not allowed (340ms)      should run doStateChanges even if no changes are required (134ms)   Contract: FundingManager Asset     ✓ receivePayment() throws if caller is not funding asset     FundingEndedProcessVaultList()      vaultNum has correct number of payments      throws if Funding State is not "FUNDING_ENDED"      Funding State is "FUNDING_ENDED" (2326ms)     states      starts with state as New and requires a change to WAITING (76ms)      handles ENTITY state change from NEW to WAITING (883ms)      handles ENTITY state change from NEW or WAITING to FUNDING_FAILED_DONE when funding state is FAILED (4313ms)      setVaultCountPerProcess throws if value is not higher than 0      setVaultCountPerProcess properly sets value       Funding ends, has payments, but does not reach Soft Cap        handles ENTITY state change to FUNDING_FAILED_DONE, and processes all vaults (4071ms)       Funding ends, has payments, and Soft Cap is reached        handles ENTITY state change to FUNDING_SUCCESSFUL_DONE, and processes all vaults (4332ms)   Contract: FundingManager Asset     Successful funding - Token distribution       Milestone Payments only        SoftCap reached in pre-ico, 1 payment, 1 payment in pre-ico, 0 payments in ico (4917ms)        SoftCap reached in ico, 1 payment, 1 account, 0 payments in pre-ico, 1 payment in ico (4151ms)        SoftCap reached in pre-ico, 2 payments, 1 account, 1 payment in pre-ico, 1 payment in ico (5742ms)        SoftCap reached in ico, 2 payments, 1 account, 1 payment in pre-ico, 1 payment in ico (5768ms)        SoftCap reached in pre-ico, 2 payments, 2 accounts, 1 payment in pre-ico (account 1), 1 payment in ico (account 2) (5913ms)        SoftCap reached in ico, 2 payments, 2 accounts, 1 payment in pre-ico (account 1), 1 payment in ico (account 2) (5989ms)       Mixed Direct and Milestone Payments        SoftCap reached in pre-ico, 4 payments, 2 accounts, 2 payment in pre-ico (account 1/2), 2 payment in ico (account 1/2) (6023ms)     misc for extra coverage      SCADA - initCacheForVariables() throws if called by other than FundingManager (3142ms)      should run doStateChanges even if no changes are required (1118ms)      SCADA - getTokenFraction() should run 0 if my amount is 0 (3124ms)      SCADA - getUnsoldTokenFraction() should run 0 if my amount is 0 (3086ms)   Contract: Milestones Asset - Settings NOT Locked     ✓ starts with state as New and requires a change to WAITING if current time is before development start (230ms)     addRecord()      works if settings are not already locked (38ms)      throws if settings are locked (167ms)   Contract: Milestones Asset - Settings Locked     ✓ isRecordUpdateAllowed should return false (213ms)     states      throws if trying to set Meeting time after it was already set. (3471ms)      throws if now is @ expiry time and trying to set Meeting time at expiry time. (2284ms)      handles ENTITY state change from WAITING to WAITING_MEETING_TIME when current time is after development start (2567ms)      handles ENTITY state change from WAITING_MEETING_TIME to DEADLINE_MEETING_TIME_FAILED when current time is after milestone end, and meeting time was not set (3083ms)      handles ENTITY state change from WAITING_MEETING_TIME to DEADLINE_MEETING_TIME_YES when current time is after milestone end, and meeting time was set (3435ms)      handles ENTITY state change from DEADLINE_MEETING_TIME_YES to VOTING_IN_PROGRESS when current time is after meeting time (4653ms)   Contract: Proposals Asset     ✓ setVoteCountPerProcess throws if value is not higher than 0     ✓ setVoteCountPerProcess properly sets value   Contract: Proposals Asset - Settings Locked     ✓ Asset deploys and initialises properly     proposal creation       type 1 - IN_DEVELOPMENT_CODE_UPGRADE - Voting Type - Milestone        throws if called by any address other than ApplicationEntity        creates the proposal if called by the current ApplicationEntity (199ms)       type 2 - EMERGENCY_FUND_RELEASE - Voting Type - Milestone        throws if called by any address other than deployer        creates the proposal if called by the current deployer (144ms)       type 3 - MILESTONE_POSTPONING - Voting Type - Milestone        throws if called by any address other than deployer        throws if duration is not higher than min postponing bylaw        throws if duration is higher than max postponing bylaw        creates the proposal if called by the current deployer with correct duration (149ms)       type 4 - MILESTONE_DEADLINE - Voting Type - Milestone        throws if called by any address other than MilestoneAsset        creates the proposal if called by the current MilestoneAsset (147ms)       type 5 - PROJECT_DELISTING - Voting Type - Tokens        throws if called by an address that does not hold any tokens. ( none in wallet / none in vault )        throws if child application is beyond FUNDING_STARTED state. (866ms)        creates the proposal if called by a token holder, (tokens locked in vault) (153ms)        creates the proposal if called by a token holder, (tokens locked in vault) (158ms)        creates the proposal if called by a token holder, (tokens in wallet) (148ms)       misc for extra coverage        getRequiredStateChanges()        hasRequiredStateChanges()        process() throws if called by any other than ApplicationEntity        getMyVote()        getProposalState()        getBylawsMilestoneMinPostponing() (51ms)        getBylawsMilestoneMaxPostponing() (44ms)        getVotingPower() for non existent investor (40ms)   Contract: Proposals Asset - Type 1 - IN_DEVELOPMENT_CODE_UPGRADE     ✓ current proposal matches IN_DEVELOPMENT_CODE_UPGRADE settings (2982ms)     ✓ proposal closes as VOTING_RESULT_YES when time expires and no votes are registered (3295ms)     ✓ second application has all assets added, and more. Proposal closes as VOTING_RESULT_YES, state change results in assets getting transferred. (4644ms)     ✓ VOTE NO @ Milestone 3 - Proposal processed. Investor uses CashBack, validate balances, can continue with next milestones (52025ms)   Contract: Proposals Asset - Type 2 - EMERGENCY_FUND_RELEASE     ✓ current proposal matches EMERGENCY_FUND_RELEASE settings (135ms)     ✓ throws if EMERGENCY_FUND_RELEASE proposal was already created once     Proposal Created - Voting Started      throws if trying to vote on a non existing proposal (38ms)      throws if trying to vote on a the proposal while having no stake in it      Registers a valid vote if voter has a stake in the proposal, does not close voting if stake is lower than 50% (220ms)      Registers a valid vote if voter has a stake in the proposal, closes voting if stake is higher than 50% (236ms)      first vote NO stake below 50%, second vote YES above 50%, closes as VOTING_RESULT_YES (370ms)      first vote NO stake below 50%, second vote NO above 50%, closes as VOTING_RESULT_NO (201ms)      YES Vote, Annuls and registers a new valid vote if voter already voted, has a stake in the proposal, and proposal is not closed (349ms)      NO Vote, Annuls and registers a new valid vote if voter already voted, has a stake in the proposal, and proposal is not closed (329ms)      While more than 1 proposal is active, properly re-indexes active proposals once one is closed (430ms)       Voting Successful - Processed before voting expiry time        throws if trying to vote on a the proposal that has already been finalised        FundingManagerAsset state processed, releases ether to owner, tokens to investors, validates balances (3619ms)       Voting Successful - Voting time expired        FundingManagerAsset state processed, releases ether to owner, tokens to investors, validates balances (4437ms)   Contract: Proposals Asset - Type 3 - MILESTONE_POSTPONING     ✓ current proposal matches MILESTONE_POSTPONING settings (158ms)     ✓ throws if MILESTONE_POSTPONING proposal was already created once     Proposal Created - Voting Started      throws if trying to vote on a non existing proposal      throws if trying to vote on a the proposal while having no stake in it      Registers a valid vote if voter has a stake in the proposal, does not close voting if stake is lower than 50% (214ms)      Registers a valid vote if voter has a stake in the proposal, closes voting if stake is higher than 50% (234ms)      first vote NO stake below 50%, second vote YES above 50%, closes as VOTING_RESULT_YES (375ms)      first vote NO stake below 50%, second vote NO above 50%, closes as VOTING_RESULT_NO (213ms)      YES Vote, Annuls and registers a new valid vote if voter already voted, has a stake in the proposal, and proposal is not closed (368ms)      NO Vote, Annuls and registers a new valid vote if voter already voted, has a stake in the proposal, and proposal is not closed (338ms)      While more than 1 proposal is active, properly re-indexes active proposals once one is closed (415ms)       Voting Successful - Processed before voting expiry time        throws if trying to vote on a the proposal that has already been finalised        MilestoneAsset state processed, record time_end increased (1317ms)       Voting Successful - Voting time expired        MilestoneAsset state processed, record time_end increased (2606ms)   Contract: Proposals Asset - Type 4 - MILESTONE_DEADLINE     ✓ current proposal matches MILESTONE_DEADLINE settings (148ms)     ✓ throws if MILESTONE_DEADLINE proposal was already created once     Proposal Created - Voting Started      throws if trying to vote on a non existing proposal      throws if trying to vote on a the proposal while having no stake in it      Registers a valid vote if voter has a stake in the proposal (249ms)      YES Vote, Annuls and registers a new valid vote if voter already voted, has a stake in the proposal, and proposal is not closed (346ms)      NO Vote, Annuls and registers a new valid vote if voter already voted, has a stake in the proposal, and proposal is not closed (337ms)      While more than 1 proposal is active, properly re-indexes active proposals once one is closed (7987ms)       Voting Successful - Voting time expired        FundingManagerAsset state processed, releases ether to owner, tokens to investors, validates balances (6787ms)   Contract: Proposals Asset - Type 5 - PROJECT_DELISTING     ✓ current proposal matches PROJECT_DELISTING settings (132ms)     ✓ throws if PROJECT_DELISTING proposal was already created once     Proposal Created - Voting Started      throws if trying to vote on a non existing proposal      throws if trying to vote on a the proposal while having no stake in it      Registers a valid vote if voter has a stake in the proposal, does not require state changes if stake is lower than 50% (245ms)      Registers multiple votes and requires state changes if stake is higher than 50% (347ms)      Registers multiple YES votes, after processing closes as VOTING_RESULT_YES (1438ms)      Registers multiple NO votes, after processing closes as VOTING_RESULT_NO (1456ms)      Registers multiple MIXED votes ( most YES ), some change vote, after processing closes as VOTING_RESULT_YES (1553ms)      Registers multiple MIXED votes ( most NO ), some change vote, after processing closes as VOTING_RESULT_NO (1581ms)       Voting Successful - Processed before voting expiry time        throws if trying to vote on a the proposal that has already been finalised (1345ms)        ApplicationEntity state processed, ListingContract delists project (1337ms)       Voting Successful - Voting time expired        ApplicationEntity state processed, ListingContract delists project (1285ms)   Contract: Proposals Asset - Type 6 - AFTER_COMPLETE_CODE_UPGRADE     ✓ current proposal matches AFTER_COMPLETE_CODE_UPGRADE settings (859ms)     ✓ DEVELOPMENT_COMPLETE, Upgrade to second app, request upgrade to third - Proposal processed. (2453ms)   Contract: Project COMPLETION     ✓ Development started, processes all milestones, and after last one sets application into DEVELOPMENT_COMPLETE state, validates balances each step (44197ms)   Contract: CashBack Scenario Testing     Platform Funding Failed - Cashback Type 1 - Funding processed      Funding Vaults allow all investors to CashBack (232ms)      throws if CashBack is requested by other address than vault owner (investor) (86ms)      Requesting CashBack transfers all locked ether back to the investor, validates balances and gas usage (217ms)     Platform Funding Failed - Cashback Type 1 - Funding not processed      Funding Vaults allow all investors to CashBack (573ms)      throws if CashBack is requested by other address than vault owner (investor) (168ms)      Requesting CashBack transfers all locked ether back to the investor, validates balances and gas usage (249ms)      Once processed Funding Vaults do not allow CashBack (3716ms)      If not processed in time, and CashBack is active, throws if trying to process (1191ms)     Platform Funding Successful - Cashback Type 2 - Owner Missing in Action Cashback      Funding Vaults allow all investors to CashBack (1395ms)      MIA @ Milestone 1 - Requesting CashBack transfers all locked ether back to the investor, and locked tokens to platform owner, validates balances and gas usage (1403ms)      MIA @ Milestone 3 - CashBack transfers all locked ether back to the investor, and locked tokens to platform owner, validates balances and gas usage (19096ms)      MIA @ Milestone LAST - CashBack transfers all locked ether back to the investor, and locked tokens to platform owner, validates balances and gas usage (40726ms)     Platform Funding Successful - Cashback Type 3 - Milestone Release      Proposal processed. Funding Vault allows the investor to CashBack if majority voted NO and investor also voted NO (10921ms)      VOTE NO @ Milestone 1 - Proposal processed. Investor uses CashBack, validate balances (1601ms)      VOTE NO @ Milestone 1 - Proposal processed. Investor uses CashBack, validate balances, can continue with next milestones (48234ms)      VOTE NO @ Milestone 3 - Proposal processed. Investor uses CashBack, validate balances, can continue with next milestones (48125ms)      VOTE NO @ Milestone 3 - Proposal processed. Investor does not use CashBack, validate balances, can continue with next milestones (48182ms)      VOTE NO @ Milestone LAST - Proposal processed. Investor uses CashBack, validate balances (41244ms)      All investors VOTE NO and cashback at @ Milestone 3, Milestone releases now require 0 votes, automatically finalise as successful (42136ms)   314 passing (18m)

Features for everyone

General Features
  • Decentralized open-source application
  • Fair market token sale
  • Democratic voting process
  • Milestone driven development
  • In contract revenue stream
  • Trustless operations
For Investors
  • Risk indicators and analysis
  • Auction based Token Buyback
  • Token holder discounts
  • Investor platform moderation
  • Funding Vaults with escrow until delivery
  • 3 Cash Back programs
For Projects
  • Project Creation Wizard
  • Collaboration features
  • Custom distribution algorithms
  • Bounty portal & distribution tools
  • Code upgrades & token holder voting
  • Low fees - 1% of ETH Revenue
For Developers
  • Technical Documentation
  • Functional Diagrams
  • Deployment Strategies
  • MIT Licensed Source Code
  • Upgradeable Application Design
  • Community provided and voted Code Upgrades
NOTE: You are free to use our tools to launch your own. For details please see Technical Documentation and Offering Document
Platform Risk Indicators
From the inputs entered by the Project Owner in the Creation Wizard, BlockBits algorithms are automatically creating a series of risk indicators for each submitted project. These are strictly mathematic indicators based on the nature of token minting policy, accepted types of funding, relations between milestones and many others.
Development Milestones
Just like in software development, most projects can be split up in "Phases". We call them Development Milestones and each one has a percentage of the raised funds linked to it, and requires community acceptance in order for funds and tokens to be released.
Secure Vaults
Each Investor has their own separate smart contract, that stores and locks ETH and tokens until an action is available. This contract mitigates issues that can arise from hacking attempts, even successful ones, by enforcing 2 hardcoded output addresses, namely, the platform and investor wallets.
Investors Power
BlockBits token holders have unprecedented power. They can create and vote proposals and once voted they are automatically implemented. It is not a consultative but an executive vote!
Responsable Owners
During the course of platform development, project owners are not able to use their tokens in any way, they cannot sell them, nor can they vote on proposals.
BuyBack & Burn
Most of BlockBits revenue is spent on the BuyBack program which buys BlockBits tokens. These tokens are burned and the value of the remaining BlockBits tokens constantly increases.

Token sale

General Settings
Token Symbol BBX
Total Supply * See FAQ
Accepted Currency ETH Only
Sale Soft Cap 5000 ETH
Sale Hard Cap 35000 ETH
1. PRE-ICO
Start 4th of Feb 2018
End 28th of Feb 2018
1 ETH 9800 BBX
Hard Cap 7000 ETH
Raised 5.2594 ETH
2. ICO
Start 10th of March 2018
End 1st of May 2018
1 ETH 7000 BBX
Hard Cap 35000 ETH *incl PRE-ICO
Remaining 34658.6306 ETH
Check out the Contribute Page for detailed statistics and results.

Funding Methods

A - Direct Funding
Direct Funding payments will lock ETH until either the project is successfully funded, or it fails. If the project is successfully funded, the ETH is released to the platform's multi signature wallet address, and tokens get sent to the vault's owner wallet address. If the project's funding fails, the funds are unlocked and can be claimed back by the vault's owner.
* This gives you all the tokens once funding is successful and you get to moderate the platform as long as you own the tokens.
Token Release After Funding
Development Control No
Platform Control Yes
Minimum Entry none
B - Milestone Funding
Milestone Funding payments adhere to the same rules as Direct funding when it comes to incoming funds and release in case of funding failure. The fundamental difference is that, if the project's funding is successful, funds and tokens get released only upon successful completion and voting by investors in development milestones.
* This gives you a percentage of the tokens each time the team delivers on a milestone. You get to moderate the platform and validate the delivery of development milestones.
Token Release % After Each Milestone
Development Control Yes
Platform Control Yes
Minimum Entry none

Funding And Token Distribution

40%
Project
Token
Distribution
3%
Bounty
57%
Sale
* Project's tokens are locked for the entire duration of the Development Milestones.
* Bounty pool tokens are released upon funding completion.
Milestone Funding Distribution
Milestone Name Percentage
Minimalistic Platform 20%
3rd Party Launch Functionality 20%
Code Upgrade Tools and Token Buyback 10%
Basic Risk indicators and Collaboration tools 15%
Advanced functionality 15%
Token Holder Upgrades 10%
Full Decentralization 10%

Roadmap

Phase 1 - Proof of Concept
June 2017 - January 2018
The
Documentation
  • Technical Documentation
  • Functional Diagrams
  • Deployment Strategy and Flows
  • Live Documentation
The
Code
  • Backend Application MVP
  • 300+ Unit and Integration Tests
The
Tools
  • Bounty Portal
  • Bounty Program Tools
  • Mobile Applications
The
Offering
  • Platform identity - Logo and Design
  • Campaign Ofering Whitepaper
  • Campaign Landing Page
Landing
Redesign
  • Reverting to Standard Token Sale
  • BlockBits Info Flow Diagrams
  • New Explainer Video
  • Explainer Articles
Phase 2 - Funding
January 2018 - May 2018
Funding
Start
  • Announcements
  • Funding Campaign Launch
  • AMA interviews
  • Press releases
The
PRE ICO
  • 4th of February 2018
  • 28th of February 2018
The
ICO
  • 10th March 2018
  • 1st May 2018
Token
Allocation
  • 2nd of May 2018
  • Direct Funding Pool - Token unlock
  • Bounty Portal Pool - Token unlock
Phase 3 - Development
May 2018 - May 2020
Development
Start
  • 5th of May 2018
Minimalistic
Platform
  • Estimated Duration: 90 days
  • Team expansion
  • Swarm / IPFS Storage
  • Platform Web Application
  • Campaign Page
  • Campaign Listing and filtering
  • My Profile
  • MainNet / TestNet Testing environments
  • Deployment Tools
  • Application State Processing Daemon
  • Minimum required functionality in order for token holders to be able to validate and vote on proposals.
3rd Party Launch
Functionality
  • Estimated Duration: 180 days
  • Platform Web Application
  • Campaign Page improvements
  • Campaign Listing and filtering improvements
  • Project Creation Wizard - v1
  • BlockChain Application Deployer
  • Platform - Revenue Stream Storage Contract
  • Mobile Application Update
  • Minimum required functionality to allow 3rd party projects to launch through the platform and allow token holders to participate in funding events that include discount programs.
Code Upgrade Tools
and Token Buyback
  • Estimated Duration: 90 days
  • Campaign Page
    • Code Upgrade Tools with in platform code diff viewer
    • Token Buyback functionality that uses funds in Revenue Stream Storage
  • Minimum required functionality to allow Code Upgrades to be processed in order to enable Token Buyback for the main platform and launched children projects.
Basic Risk indicators
and Collaboration tools
  • Estimated Duration: 90 days
  • Campaign Page
    • Campaign Risk indications and analysis
  • Campaign listing and filtering based on risk indicators and scoring
  • Project Creation Wizard - v2
    • Collaboration Tools
    • New Discount programs
    • New Funding algorithms
  • Basic Risk analysis and indicators for projects and Collaboration tools for the Creation Wizard.
Advanced
functionality
  • Estimated Duration: 90 days
  • Project Creation Wizard - v3
    • Funding Auction Bidding
  • Campaign Page
    • Advanced Risk indications and analysis
  • Advanced functionality for project creation, risk analysis and indicators for project page details.
Token Holder
Upgrades
  • Estimated Duration: 90 days
  • Token holder initiated Code Upgrades that get paid from the Revenue Stream Storage Contract
  • Allows token holders to propose upgrades and get paid for them.
Full
Decentralization
  • Estimated Duration: 90 days
  • Full Decentralization Support
    • ENS Ownership & ENS annual renewal payments
    • Storage Ownership with renewal
  • Project gets prepared for completion, where no one owns it.

Platform Applications

Bounty Portal
If you haven't already, sign up for a Bounty Portal account and earn tokens by spreading our mission.
* Launched on the 14th of January 2018.
Mobile Application
A complementary application you can install on your phone, to get notifications about events and news related to the platform. It will notify you each time you, as an investor need to vote for a proposal in the platform, or when a new project is launched.
* Currently in development.
Wizard Demo
The BlockBits DAPP Creation Wizard is the main step a Project Owner has to perform in order to launch a new project. After the wizard setup is completed the new project is not only listed on the BlockBits platform but it also becomes a self sufficient DAPP on the Ethereum blockchain.
* Implementation details can be found in our documentation.
* Currently in development.

Advisors

Ravi Singh
Business & Technology Leader | Growth Hacker
Alexandru Lazar
Emerging Technologies Enthusiast
Sandeep Patel
Managing Partner
Richard Johnson
Digital Consultant ( Security | Technology )
Georgeana Bobos-Kristof
Mathematics Professor / Educational Consultant
Tiberiu Socaci
Business Development Manager

Core Team

Micky Socaci
CEO and Lead Developer
Mihai Iliescu
Senior Security Engineer
Vlad Morar
Video / Marketing Specialist
Ionut Toader
Frontend Developer
Radu Dumitru
Graphic / UX Designer
Arthur Birnbaum
Animation and Motion Graphics
@lynceus
Bussines Analyst / Developer