Correct update of read values following write to use byte addresses

library AVMMemoryContext32 {
    struct Context {
        uint256[] readAccesses;
        uint256[] writeAccesses;
        uint writeIdx;
        uint cachedRead;
        uint cachedReadValue;
        uint addressMask;
        bool valid;
    }

    event trace(string);
    event traceNum(uint);
    event MissingRead(uint);
    event BadWriteAddress(uint, uint);
    event BadWriteValue(uint, uint, uint);
    function initContext(uint256[] memory readAccesses, uint256[] memory writeAccesses, uint addressBits) internal returns (Context memory) {
        Context memory ctx;
        ctx.readAccesses = readAccesses;
        ctx.writeAccesses = writeAccesses;
        ctx.writeIdx = 0;
        ctx.addressMask = (2 ** addressBits) - 1;
        ctx.cachedRead = (uint) (-1);
        ctx.cachedReadValue = 0;
        ctx.valid = true;
        return ctx;
    }

    function read256(Context ctx, uint addr) internal returns (uint) {
        if (!ctx.valid) return 0;

        uint v;
        addr = addr & ctx.addressMask;

        for (uint i = 0; i < ctx.readAccesses.length; i += 2) {
            if (ctx.readAccesses[i] == (addr / 32)) {
                return ctx.readAccesses[i+1];
            }
        }

        ctx.valid = false;
        MissingRead(addr / 32);
        return 0;
    }

    function read32(Context ctx, uint addr) internal returns (uint32) {
        uint v = read256(ctx, addr);

        // Shift down to chosen word
        for (uint j = ((addr / 4) % 8); j < 7; j++) {
            v = v / 4294967296;
        }

        return (uint32) (v);
    }

    function readByte(Context ctx, uint addr) internal returns (uint8) {
        uint32 v = read32(ctx, addr);

        for (uint j = (addr % 4); j < 3; j++) {
            v = v / 256;
        }

        return (uint8) (v);
    }

    function write256(Context ctx, uint addr, uint value) internal {
        if (!ctx.valid) return;
        addr = addr & ctx.addressMask;

        trace("Write");
        if (ctx.writeAccesses.length < (ctx.writeIdx + 2)) {
            // Insufficient writes
            trace("Insufficient Writes");
            ctx.valid = false;
            return;
        }

        trace("Reading write address");
        if (ctx.writeAccesses[ctx.writeIdx++] != (addr / 32)) {
            // Wrong write address
            BadWriteAddress(addr / 32, ctx.writeAccesses[ctx.writeIdx-1]);
            ctx.valid = false;
            return;
        }

        // Whole overwrite - ignore prior value
        ctx.writeIdx++;

        trace("Reading write value");
        if (ctx.writeAccesses[ctx.writeIdx++] != value) {
            // Wrong write value
            BadWriteValue(addr / 32, value, ctx.writeAccesses[ctx.writeIdx - 1]);
            ctx.valid = false;
            return;
        }

        trace("Updating read values for write");
        for (uint i = 0; i < ctx.readAccesses.length; i += 2) {
            if (ctx.readAccesses[i] == addr / 32) {
                ctx.readAccesses[i+1] = value;
            }
        }
    }

    function write32(Context ctx, uint addr, uint value) internal {
        if (!ctx.valid) return;
        addr = addr & ctx.addressMask;

        trace("Write");
        if (ctx.writeAccesses.length < (ctx.writeIdx + 2)) {
            // Insufficient writes
            trace("Insufficient Writes");
            ctx.valid = false;
            return;
        }

        trace("Reading write address");
        if (ctx.writeAccesses[ctx.writeIdx++] != (addr / 32)) {
            // Wrong write address
            BadWriteAddress(addr / 32, ctx.writeAccesses[ctx.writeIdx-1]);
            ctx.valid = false;
            return;
        }

        trace("Reading write prior value");
        uint result = ctx.writeAccesses[ctx.writeIdx++];
        uint mask = 4294967295;
        value = value & mask;

        // Shift up to chosen word
        for (uint j = ((addr / 4) % 8); j < 7; j++) {
            mask = mask * 4294967296;
            value = value * 4294967296;
        }

        result = (result & (~mask)) | value;

        trace("Reading write value");
        if (ctx.writeAccesses[ctx.writeIdx++] != result) {
            // Wrong write value
            BadWriteValue(addr / 32, value, ctx.writeAccesses[ctx.writeIdx - 1]);
            ctx.valid = false;
            return;
        }

        trace("Updating future read values from write");
        for (uint i = 0; i < ctx.readAccesses.length; i += 2) {
            if (ctx.readAccesses[i] == addr / 32) {
                ctx.readAccesses[i+1] = value;
            }
        }
    }

    function isValid(Context memory ctx) internal returns (bool) {
        if (ctx.writeAccesses.length != ctx.writeIdx) {
            // Excess reads
            ctx.valid = false;
        }
        return ctx.valid;
    }
}

library AVMMemoryContext32 {
    struct Context {
        uint256[] readAccesses;
        uint256[] writeAccesses;
        uint writeIdx;
        uint cachedRead;
        uint cachedReadValue;
        uint addressMask;
        bool valid;
    }

    event trace(string);
    event traceNum(uint);
    event MissingRead(uint);
    event BadWriteAddress(uint, uint);
    event BadWriteValue(uint, uint, uint);
    function initContext(uint256[] memory readAccesses, uint256[] memory writeAccesses, uint addressBits) internal returns (Context memory) {
        Context memory ctx;
        ctx.readAccesses = readAccesses;
        ctx.writeAccesses = writeAccesses;
        ctx.writeIdx = 0;
        ctx.addressMask = (2 ** addressBits) - 1;
        ctx.cachedRead = (uint) (-1);
        ctx.cachedReadValue = 0;
        ctx.valid = true;
        return ctx;
    }

    function read256(Context ctx, uint addr) internal returns (uint) {
        if (!ctx.valid) return 0;

        uint v;
        addr = addr & ctx.addressMask;

        for (uint i = 0; i < ctx.readAccesses.length; i += 2) {
            if (ctx.readAccesses[i] == (addr / 32)) {
                return ctx.readAccesses[i+1];
            }
        }

        ctx.valid = false;
        MissingRead(addr / 32);
        return 0;
    }

    function read32(Context ctx, uint addr) internal returns (uint32) {
        uint v = read256(ctx, addr);

        // Shift down to chosen word
        for (uint j = ((addr / 4) % 8); j < 7; j++) {
            v = v / 4294967296;
        }

        return (uint32) (v);
    }

    function readByte(Context ctx, uint addr) internal returns (uint8) {
        uint32 v = read32(ctx, addr);

        for (uint j = (addr % 4); j < 3; j++) {
            v = v / 256;
        }

        return (uint8) (v);
    }

    function write256(Context ctx, uint addr, uint value) internal {
        if (!ctx.valid) return;
        addr = addr & ctx.addressMask;

        trace("Write");
        if (ctx.writeAccesses.length < (ctx.writeIdx + 2)) {
            // Insufficient writes
            trace("Insufficient Writes");
            ctx.valid = false;
            return;
        }

        trace("Reading write address");
        if (ctx.writeAccesses[ctx.writeIdx++] != (addr / 32)) {
            // Wrong write address
            BadWriteAddress(addr / 32, ctx.writeAccesses[ctx.writeIdx-1]);
            ctx.valid = false;
            return;
        }

        // Whole overwrite - ignore prior value
        ctx.writeIdx++;

        trace("Reading write value");
        if (ctx.writeAccesses[ctx.writeIdx++] != value) {
            // Wrong write value
            BadWriteValue(addr / 32, value, ctx.writeAccesses[ctx.writeIdx - 1]);
            ctx.valid = false;
            return;
        }

        trace("Updating read values for write");
        for (uint i = 0; i < ctx.readAccesses.length; i += 2) {
            if (ctx.readAccesses[i] == addr) {
                ctx.readAccesses[i+1] = value;
            }
        }
    }

    function write32(Context ctx, uint addr, uint value) internal {
        if (!ctx.valid) return;
        addr = addr & ctx.addressMask;

        trace("Write");
        if (ctx.writeAccesses.length < (ctx.writeIdx + 2)) {
            // Insufficient writes
            trace("Insufficient Writes");
            ctx.valid = false;
            return;
        }

        trace("Reading write address");
        if (ctx.writeAccesses[ctx.writeIdx++] != (addr / 32)) {
            // Wrong write address
            BadWriteAddress(addr / 32, ctx.writeAccesses[ctx.writeIdx-1]);
            ctx.valid = false;
            return;
        }

        trace("Reading write prior value");
        uint result = ctx.writeAccesses[ctx.writeIdx++];
        uint mask = 4294967295;
        value = value & mask;

        // Shift up to chosen word
        for (uint j = ((addr / 4) % 8); j < 7; j++) {
            mask = mask * 4294967296;
            value = value * 4294967296;
        }

        result = (result & (~mask)) | value;

        trace("Reading write value");
        if (ctx.writeAccesses[ctx.writeIdx++] != result) {
            // Wrong write value
            BadWriteValue(addr / 32, value, ctx.writeAccesses[ctx.writeIdx - 1]);
            ctx.valid = false;
            return;
        }

        trace("Updating future read values from write");
        for (uint i = 0; i < ctx.readAccesses.length; i += 2) {
            if (ctx.readAccesses[i] == addr) {
                ctx.readAccesses[i+1] = value;
            }
        }
    }

    function isValid(Context memory ctx) internal returns (bool) {
        if (ctx.writeAccesses.length != ctx.writeIdx) {
            // Excess reads
            ctx.valid = false;
        }
        return ctx.valid;
    }
}


use safeTransfer

use safeTransfer

pragma solidity ^0.4.11;

import './ERC20Basic.sol';
import './SafeERC20.sol';
import '../ownership/Ownable.sol';
import '../math/Math.sol';
import '../math/SafeMath.sol';

/**
 * @title TokenVesting
 * @dev A token holder contract that can release its token balance gradually like a
 * typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
 * owner.
 */
contract TokenVesting is Ownable {
  using SafeMath for uint256;
  using SafeERC20 for ERC20Basic;

  event Released(uint256 amount);
  event Revoked();

  // beneficiary of tokens after they are released
  address public beneficiary;

  uint256 public cliff;
  uint256 public start;
  uint256 public duration;

  bool public revocable;

  mapping (address => uint256) public released;
  mapping (address => bool) public revoked;

  /**
   * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
   * _beneficiary, gradually in a linear fashion until _start + _duration. By then all
   * of the balance will have vested.
   * @param _beneficiary address of the beneficiary to whom vested tokens are transferred
   * @param _cliff duration in seconds of the cliff in which tokens will begin to vest
   * @param _duration duration in seconds of the period in which the tokens will vest
   * @param _revocable whether the vesting is revocable or not
   */
  function TokenVesting(address _beneficiary, uint256 _start, uint256 _cliff, uint256 _duration, bool _revocable) {
    require(_beneficiary != 0x0);
    require(_cliff <= _duration);

    beneficiary = _beneficiary;
    revocable = _revocable;
    duration = _duration;
    cliff = _start + _cliff;
    start = _start;
  }

  /**
   * @notice Transfers vested tokens to beneficiary.
   * @param token ERC20 token which is being vested
   */
  function release(ERC20Basic token) public {
    uint256 vested = vestedAmount(token);

    require(vested > 0);

    token.safeTransfer(beneficiary, vested);

    released[token] = released[token].add(vested);

    Released(vested);
  }

  /**
   * @notice Allows the owner to revoke the vesting. Tokens already vested
   * remain in the contract, the rest are returned to the owner.
   * @param token ERC20 token which is being vested
   */
  function revoke(ERC20Basic token) public onlyOwner {
    require(revocable);
    require(!revoked[token]);

    uint256 balance = token.balanceOf(this);

    uint256 vested = vestedAmount(token);
    uint256 vesting = balance - vested;

    revoked[token] = true;

    token.safeTransfer(owner, vesting);

    Revoked();
  }

  /**
   * @dev Calculates the amount that has already vested but hasn't been released yet.
   * @param token ERC20 token which is being vested
   */
  function vestedAmount(ERC20Basic token) public constant returns (uint256) {
    if (now < cliff) {
      return 0;
    } else if (now >= start + duration || revoked[token]) {
      return token.balanceOf(this);
    } else {
      uint256 currentBalance = token.balanceOf(this);
      uint256 totalBalance = currentBalance.add(released[token]);

      uint256 vested = totalBalance.mul(now - start).div(duration);
      uint256 unreleased = vested.sub(released[token]);

      // currentBalance can be 0 in case of vesting being revoked earlier.
      return Math.min256(currentBalance, unreleased);
    }
  }
}

pragma solidity ^0.4.11;

import './ERC20Basic.sol';
import '../ownership/Ownable.sol';
import '../math/Math.sol';
import '../math/SafeMath.sol';

/**
 * @title TokenVesting
 * @dev A token holder contract that can release its token balance gradually like a
 * typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
 * owner.
 */
contract TokenVesting is Ownable {
  using SafeMath for uint256;

  event Released(uint256 amount);
  event Revoked();

  // beneficiary of tokens after they are released
  address public beneficiary;

  uint256 public cliff;
  uint256 public start;
  uint256 public duration;

  bool public revocable;

  mapping (address => uint256) public released;
  mapping (address => bool) public revoked;

  /**
   * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
   * _beneficiary, gradually in a linear fashion until _start + _duration. By then all
   * of the balance will have vested.
   * @param _beneficiary address of the beneficiary to whom vested tokens are transferred
   * @param _cliff duration in seconds of the cliff in which tokens will begin to vest
   * @param _duration duration in seconds of the period in which the tokens will vest
   * @param _revocable whether the vesting is revocable or not
   */
  function TokenVesting(address _beneficiary, uint256 _start, uint256 _cliff, uint256 _duration, bool _revocable) {
    require(_beneficiary != 0x0);
    require(_cliff <= _duration);

    beneficiary = _beneficiary;
    revocable = _revocable;
    duration = _duration;
    cliff = _start + _cliff;
    start = _start;
  }

  /**
   * @notice Transfers vested tokens to beneficiary.
   * @param token ERC20 token which is being vested
   */
  function release(ERC20Basic token) public {
    uint256 vested = vestedAmount(token);

    require(vested > 0);

    token.transfer(beneficiary, vested);

    released[token] = released[token].add(vested);

    Released(vested);
  }

  /**
   * @notice Allows the owner to revoke the vesting. Tokens already vested
   * remain in the contract, the rest are returned to the owner.
   * @param token ERC20 token which is being vested
   */
  function revoke(ERC20Basic token) public onlyOwner {
    require(revocable);
    require(!revoked[token]);

    uint256 balance = token.balanceOf(this);

    uint256 vested = vestedAmount(token);
    uint256 vesting = balance - vested;

    revoked[token] = true;

    token.transfer(owner, vesting);

    Revoked();
  }

  /**
   * @dev Calculates the amount that has already vested but hasn't been released yet.
   * @param token ERC20 token which is being vested
   */
  function vestedAmount(ERC20Basic token) public constant returns (uint256) {
    if (now < cliff) {
      return 0;
    } else if (now >= start + duration || revoked[token]) {
      return token.balanceOf(this);
    } else {
      uint256 currentBalance = token.balanceOf(this);
      uint256 totalBalance = currentBalance.add(released[token]);

      uint256 vested = totalBalance.mul(now - start).div(duration);
      uint256 unreleased = vested.sub(released[token]);

      // currentBalance can be 0 in case of vesting being revoked earlier.
      return Math.min256(currentBalance, unreleased);
    }
  }
}


Implement initial scoring in Twitter

Implement initial scoring in Twitter

//
// This contract will validate that a twitter message url:
// 1) corresponds to a given username
// 2) containts an expected message (the user identifier)
//

import "accountProviderBase.sol";

contract Twitter is accountProviderBase {
  Lookup lookup;

  address owner;

  modifier owneronly { if (msg.sender == owner) _ }

  function setOwner(address addr) owneronly {
    owner = addr;
  }

  function Twitter() {
    owner = msg.sender;
  }

  function setLookup(address addr) owneronly {
    lookup = Lookup(addr);
  }

  // map the expected identifier to an oraclize identifier
  mapping (bytes32 => bytes32) expectedId;

  // true if verification, otherwise scoring
  mapping (bytes32 => bool) isVerification;

  // callback from oraclize with the result, let the storage contract know
  function __callback(bytes32 myid, string result) {
    if (msg.sender != oraclize_cbAddress()) throw;

    if (isVerification[myid])
      processVerification(myid, result);
    else
      processScore(myid, result);

    // clean up
    delete expectedId[myid];
    delete isVerification[myid];
  }

  function processScore(bytes32 myid, string result) internal {
    uint followers = parseInt(result);
    uint newScore = 1000000;
    if (followers / 10000 == 0)
      newScore = 100 * (followers % 10000);

    Storage(lookup.addrStorage()).updateScore(lookup.accountProvider_TWITTER(), expectedId[myid], newScore);
  }

  // start the scoring process and call oraclize with the URL
  function score(bytes32 id, string userId) coupon("HackEtherCamp") {
    bytes memory _userId = bytes(userId);
    string memory head = "html(https://twitter.com/";
    bytes memory _head = bytes(head);
    string memory tail = ").xpath(//*[contains(@data-nav, 'followers')]/*[contains(@class, 'ProfileNav-value')]/text())";
    bytes memory _tail = bytes(tail);
    string memory query = new string(_head.length + _userId.length + _tail.length);
    bytes memory _query = bytes(query);
    uint i = 0;
    for (uint j = 0; j < _head.length; j++)
      _query[i++] = _head[j];
    for (j = 0; j < _userId.length; j++)
      _query[i++] = _userId[j];
    for (j = 0; j < _tail.length; j++)
      _query[i++] = _tail[j];
    bytes32 oraclizeId = oraclize_query("URL", query);
    expectedId[oraclizeId] = id;
    isVerification[oraclizeId] = false;
  }

  function processVerification(bytes32 myid, string result) internal {
    // this is basically a bytes32 to hexstring piece
    string memory expected = iudexIdToString(expectedId[myid]);
    bool asExpected = strCompare(expected, result) == 0;
    Storage(lookup.addrStorage()).updateAccount(lookup.accountProvider_TWITTER(), expectedId[myid], asExpected, myid);
  }

  // ensure that the proofLocation corresponds to a twitter.com URL for the user `userId`
  function verifyUrl(string userId, string proofLocation) internal returns (bool){
    bytes memory _userId = bytes(userId);
    string memory twitterPrefix = "://twitter.com/";
    bytes memory _twitterPrefix = bytes(twitterPrefix);
    string memory urlHead = new string(_twitterPrefix.length + _userId.length + 1);
    bytes memory _urlHead = bytes(urlHead);
    uint i = 0;
    for (uint j = 0; j < _twitterPrefix.length; j++)
      _urlHead[i++] = _twitterPrefix[j];
    for (j = 0; j < _userId.length; j++)
      _urlHead[i++] = _userId[j];
    _urlHead[i++] = byte("/");

    if (indexOf(proofLocation, string(_urlHead)) == -1)
      return false;

    return true;
  }

  // start the verification process and call oraclize with the URL
  function verify(bytes32 id, string userId, string proofLocation) coupon("HackEtherCamp") {
  //    bytes32 oraclizeId = oraclize_query("html(https://twitter.com/oraclizeit/status/671316655893561344).xpath(//*[contains(@class, 'tweet-text')]/text())");

    // check that userId matches the username in proofLocation
    if (!verifyUrl(userId, proofLocation))
      throw;

    // build up the request string
    string memory head = "html(";
    bytes memory _head = bytes(head);
    string memory tail = ").xpath(//*[contains(@class, 'tweet-text')]/text())";
    bytes memory _tail = bytes(tail);

    bytes memory _tweetUrl = bytes(proofLocation);

    string memory query = new string(_head.length + _tail.length + _tweetUrl.length + 2);
    bytes memory _query = bytes(query);
    uint i = 0;
    for (uint j = 0; j < _head.length; j++)
      _query[i++] = _head[j];
    for (j = 0; j < _tweetUrl.length; j++)
      _query[i++] = _tweetUrl[j];
    for (j = 0; j < _tail.length; j++)
      _query[i++] = _tail[j];
    _query[i++] = 0;

    bytes32 oraclizeId = oraclize_query("URL", query);
    expectedId[oraclizeId] = id;
    isVerification[oraclizeId] = true;
  }
}

//
// This contract will validate that a twitter message url:
// 1) corresponds to a given username
// 2) containts an expected message (the user identifier)
//

import "accountProviderBase.sol";

contract Twitter is accountProviderBase {
  Lookup lookup;

  address owner;

  modifier owneronly { if (msg.sender == owner) _ }

  function setOwner(address addr) owneronly {
    owner = addr;
  }

  function Twitter() {
    owner = msg.sender;
  }

  function setLookup(address addr) owneronly {
    lookup = Lookup(addr);
  }

  // map the expected identifier to an oraclize identifier
  mapping (bytes32 => bytes32) expectedId;

  // true if verification, otherwise scoring
  mapping (bytes32 => bool) isVerification;

  // callback from oraclize with the result, let the storage contract know
  function __callback(bytes32 myid, string result) {
    if (msg.sender != oraclize_cbAddress()) throw;

    if (isVerification[myid])
      processVerification(myid, result);
    else
      processScore(myid, result);

    // clean up
    delete expectedId[myid];
    delete isVerification[myid];
  }

  function processScore(bytes32 myid, string result) internal {
    // FIXME: implement the actual processing/calculation
    Storage(lookup.addrStorage()).updateScore(lookup.accountProvider_TWITTER(), expectedId[myid], 0);
  }

  // start the scoring process and call oraclize with the URL
  function score(bytes32 id, string userId) coupon("HackEtherCamp") {
    // FIXME: implement the actual query
    string memory query = "this-will-fail";

    bytes32 oraclizeId = oraclize_query("URL", query);
    expectedId[oraclizeId] = id;
    isVerification[oraclizeId] = false;
  }

  function processVerification(bytes32 myid, string result) internal {
    // this is basically a bytes32 to hexstring piece
    string memory expected = iudexIdToString(expectedId[myid]);
    bool asExpected = strCompare(expected, result) == 0;
    Storage(lookup.addrStorage()).updateAccount(lookup.accountProvider_TWITTER(), expectedId[myid], asExpected, myid);
  }

  // ensure that the proofLocation corresponds to a twitter.com URL for the user `userId`
  function verifyUrl(string userId, string proofLocation) internal returns (bool){
    bytes memory _userId = bytes(userId);
    string memory twitterPrefix = "://twitter.com/";
    bytes memory _twitterPrefix = bytes(twitterPrefix);
    string memory urlHead = new string(_twitterPrefix.length + _userId.length + 1);
    bytes memory _urlHead = bytes(urlHead);
    uint i = 0;
    for (uint j = 0; j < _twitterPrefix.length; j++)
      _urlHead[i++] = _twitterPrefix[j];
    for (j = 0; j < _userId.length; j++)
      _urlHead[i++] = _userId[j];
    _urlHead[i++] = byte("/");

    if (indexOf(proofLocation, string(_urlHead)) == -1)
      return false;

    return true;
  }

  // start the verification process and call oraclize with the URL
  function verify(bytes32 id, string userId, string proofLocation) coupon("HackEtherCamp") {
  //    bytes32 oraclizeId = oraclize_query("html(https://twitter.com/oraclizeit/status/671316655893561344).xpath(//*[contains(@class, 'tweet-text')]/text())");

    // check that userId matches the username in proofLocation
    if (!verifyUrl(userId, proofLocation))
      throw;

    // build up the request string
    string memory head = "html(";
    bytes memory _head = bytes(head);
    string memory tail = ").xpath(//*[contains(@class, 'tweet-text')]/text())";
    bytes memory _tail = bytes(tail);

    bytes memory _tweetUrl = bytes(proofLocation);

    string memory query = new string(_head.length + _tail.length + _tweetUrl.length + 2);
    bytes memory _query = bytes(query);
    uint i = 0;
    for (uint j = 0; j < _head.length; j++)
      _query[i++] = _head[j];
    for (j = 0; j < _tweetUrl.length; j++)
      _query[i++] = _tweetUrl[j];
    for (j = 0; j < _tail.length; j++)
      _query[i++] = _tail[j];
    _query[i++] = 0;

    bytes32 oraclizeId = oraclize_query("URL", query);
    expectedId[oraclizeId] = id;
    isVerification[oraclizeId] = true;
  }
}


Added mapping to translate tag implementations into addresses and removed redundant address array from Tag contract (and modified related functions to reflect this)

contract Master
{
  function Master()
  {

  }
  //Initialize master data store
  mapping(address => uint) tokenBalance;
  mapping(address => string) tagName;
  mapping(string => address) tagAddressFromName;
  mapping(address => Tag) tagImplementation;
  mapping(Tag => address) tagAddressFromImplementation;
  mapping(address => string[]) acheivements;

  function addTag(string name, address[] parentList) returns(uint) //Creates a new tag contract
  {
    uint response = 0;
    if(tokenBalance[msg.sender] < 1)
    {
      response += 1;
    }
    if(tagAddress[name] == 0)
    {
      response += 10;
    }
    if(response==0)
    {
      Tag newTag;
      address newTagAddress = address(newTag);
      tagName[newTagAddress] = name;
      tagAddressFromName[name] = newTagAddress;
      tagImplementation[newTagAddress] = newTag;
      tagAddressFromImplementation[newTag] = newTagAddress;
      for(uint i=0; i<= parentList.length; i++) //adds all the given parents
      {
        if(parentList[i]==0)
        {
          response += 100;
        }
        if(response==0)
        {
          newTag.addParent(tagImplementation[parentList[i]]);
        }
      }
    }
    newTag.setMaster(this);
    return response;
  }
}

//Defines the meta-contract for a Tag
contract Tag
{
  Tag[] parentTags;
  Master master;
  address[] owners; //Those who have earned the tag
  mapping(address => address[]) assessmentHistory; //All assessments completed
  mapping(address => uint) scores; //All positive assessements scores
  function Tag()
  {

  }
  function addParent(Tag parentTag)
  {
    parentTags.push(parentTag);
  }
  function setMaster(Master m)
  {
    master = m;
  }
  function getAssessors(uint randomNumber)
  {

  }
  function startAssessment(address assessee, address[] assessors)
  {
    Assessment newAssessment;
    newAssessment.setAssessee(assessee);
    newAssessment.setAssessors(assessors);
    newAssessment.setTag(this);
  }
  function getAssessmentResults(bool result, uint score, address assessee, address assessment) returns(bool)
  {
    if(result == true)
    {
      owners.push(assessee);
      scores[assessee] = score;
      master.acheivements[assessee].push(master.tagName[address(this)]);
    }
    assessmentHistory[assessee].push(assessment);
    return result;
  }
}

//Defines the meta-contract for an assessment
contract Assessment
{
  address assessee; //We need a better word for this
  address[] assessors;
  Tag tag;
  mapping(address => uint[]) assessmentData; //Given by the assessors as IPFS hashes
  mapping(address => uint[]) assessmentAnswers; //Given by the assessee as IPFS hashes
  mapping(address => bool[]) assessmentResults; //Pass/Fail given by assessors
  mapping(address => uint[]) assessmentScores; //Numerical score given by assessors

  function Assessment()
  {

  }
  function setAssessee(address newAssessee)
  {
    assessee = newAssessee;
  }
  function setAssessors(address[] newAssessors)
  {
    assessors = newAssessors;
  }
  function setTag(Tag t)
  {
    tag = t;
  }
  function assess()
  {

  }
  function cashout()
  {

  }
}

contract Master
{
  function Master()
  {

  }
  //Initialize master data store
  mapping(address => uint) tokenBalance;
  mapping(address => string) tagName;
  mapping(string => address) tagAddress;
  mapping(address => Tag) tagImplementation;
  mapping(address => string[]) acheivements;

  function addTag(string name, address[] parentList) returns(uint) //Creates a new tag contract
  {
    uint response = 0;
    if(tokenBalance[msg.sender] < 1)
    {
      response += 1;
    }
    if(tagAddress[name] == 0)
    {
      response += 10;
    }
    if(response==0)
    {
      Tag newTag;
      address newTagAddress = address(newTag);
      tagName[newTagAddress] = name;
      tagAddress[name] = newTagAddress;
      tagImplementation[newTagAddress] = newTag;
      for(uint i=0; i<= parentList.length; i++) //adds all the given parents
      {
        if(parentList[i]==0)
        {
          response += 100;
        }
        if(response==0)
        {
          newTag.addParent(parentList[i],tagImplementation[parentList[i]]);
        }
      }
    }
    newTag.setMaster(this);
    return response;
  }
}

//Defines the meta-contract for a Tag
contract Tag
{
  address[] parents; //The tags this is a subset of
  Tag[] parentTags;
  Master master;
  address[] owners; //Those who have earned the tag
  mapping(address => address[]) assessmentHistory; //All assessments completed
  mapping(address => uint) scores; //All positive assessements scores
  function Tag()
  {

  }
  function addParent(address parent, Tag parentTag)
  {
    parents.push(parent);
    parentTags.push(parentTag);
  }
  function setMaster(Master m)
  {
    master = m;
  }
  function getAssessors(uint randomNumber)
  {

  }
  function startAssessment(address assessee, address[] assessors)
  {
    Assessment newAssessment;
    newAssessment.setAssessee(assessee);
    newAssessment.setAssessors(assessors);
    newAssessment.setTag(this);
  }
  function getAssessmentResults(bool result, uint score, address assessee, address assessment) returns(bool)
  {
    if(result == true)
    {
      owners.push(assessee);
      scores[assessee] = score;
      master.acheivements[assessee].push(master.tagName[address(this)]);
    }
    assessmentHistory[assessee].push(assessment);
    return result;
  }
}

//Defines the meta-contract for an assessment
contract Assessment
{
  address assessee; //We need a better word for this
  address[] assessors;
  Tag tag;
  mapping(address => uint[]) assessmentData; //Given by the assessors as IPFS hashes
  mapping(address => uint[]) assessmentAnswers; //Given by the assessee as IPFS hashes
  mapping(address => bool[]) assessmentResults; //Pass/Fail given by assessors
  mapping(address => uint[]) assessmentScores; //Numerical score given by assessors

  function Assessment()
  {

  }
  function setAssessee(address newAssessee)
  {
    assessee = newAssessee;
  }
  function setAssessors(address[] newAssessors)
  {
    assessors = newAssessors;
  }
  function setTag(Tag t)
  {
    tag = t;
  }
  function assess()
  {

  }
  function cashout()
  {

  }
}


Fixed the errors that Jared made me put in last time

contract otlwApp
{
        function otlwApp()
        {
        }
        mapping (address => uint) tokenBalance;
        mapping (address => string) tagName;
        mapping (string => address) tagAddress;
        mapping (address => string[]) acheivements;
        function addTag(string name) returns(uint response)
        {
                if(tokenBalance[msg.sender] < 1)
                        return 1;
                if(tagAddress[name] == 0)
                        return 2;

        }
}

contract otlw-app
{
	function otlw-app()
	{
        }
	mapping (address => uint) public tokenBalance;
	mapping (address => string) public tagName;
	mapping (string => address) public tagAddress;
	mapping (address => string[]) public acheivements;
	function addTag(string name) returns(uint response)
	{
		if(tokenBalance[msg.sender] < 1)
			return 1;
		if(tokenAddress[name] =
	function addAcheivment(address user, string acheivment)
	{


explicitly mark functions public

explicitly mark functions public

pragma solidity ^0.4.11;

import './ERC20Basic.sol';
import '../ownership/Ownable.sol';
import '../math/Math.sol';
import '../math/SafeMath.sol';

/**
 * @title TokenVesting
 * @dev A token holder contract that can release its token balance gradually like a
 * typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
 * owner.
 */
contract TokenVesting is Ownable {
  using SafeMath for uint256;

  event Released(uint256 amount);
  event Revoked();

  // beneficiary of tokens after they are released
  address public beneficiary;

  uint256 public cliff;
  uint256 public start;
  uint256 public duration;

  bool public revocable;

  mapping (address => uint256) public released;
  mapping (address => bool) public revoked;

  /**
   * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
   * _beneficiary, gradually in a linear fashion until _start + _duration. By then all
   * of the balance will have vested.
   * @param _beneficiary address of the beneficiary to whom vested tokens are transferred
   * @param _cliff duration in seconds of the cliff in which tokens will begin to vest
   * @param _duration duration in seconds of the period in which the tokens will vest
   * @param _revocable whether the vesting is revocable or not
   */
  function TokenVesting(address _beneficiary, uint256 _start, uint256 _cliff, uint256 _duration, bool _revocable) {
    require(_beneficiary != 0x0);
    require(_cliff <= _duration);

    beneficiary = _beneficiary;
    revocable = _revocable;
    duration = _duration;
    cliff = _start + _cliff;
    start = _start;
  }

  /**
   * @notice Transfers vested tokens to beneficiary.
   * @param token ERC20 token which is being vested
   */
  function release(ERC20Basic token) public {
    uint256 vested = vestedAmount(token);

    require(vested > 0);

    token.transfer(beneficiary, vested);

    released[token] = released[token].add(vested);

    Released(vested);
  }

  /**
   * @notice Allows the owner to revoke the vesting. Tokens already vested
   * remain in the contract, the rest are returned to the owner.
   * @param token ERC20 token which is being vested
   */
  function revoke(ERC20Basic token) public onlyOwner {
    require(revocable);
    require(!revoked[token]);

    uint256 balance = token.balanceOf(this);

    uint256 vested = vestedAmount(token);
    uint256 vesting = balance - vested;

    revoked[token] = true;

    token.transfer(owner, vesting);

    Revoked();
  }

  /**
   * @dev Calculates the amount that has already vested but hasn't been released yet.
   * @param token ERC20 token which is being vested
   */
  function vestedAmount(ERC20Basic token) public constant returns (uint256) {
    if (now < cliff) {
      return 0;
    } else if (now >= start + duration || revoked[token]) {
      return token.balanceOf(this);
    } else {
      uint256 currentBalance = token.balanceOf(this);
      uint256 totalBalance = currentBalance.add(released[token]);

      uint256 vested = totalBalance.mul(now - start).div(duration);
      uint256 unreleased = vested.sub(released[token]);

      // currentBalance can be 0 in case of vesting being revoked earlier.
      return Math.min256(currentBalance, unreleased);
    }
  }
}

pragma solidity ^0.4.11;

import './ERC20Basic.sol';
import '../ownership/Ownable.sol';
import '../math/Math.sol';
import '../math/SafeMath.sol';

/**
 * @title TokenVesting
 * @dev A token holder contract that can release its token balance gradually like a
 * typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
 * owner.
 */
contract TokenVesting is Ownable {
  using SafeMath for uint256;

  event Released(uint256 amount);
  event Revoked();

  // beneficiary of tokens after they are released
  address public beneficiary;

  uint256 public cliff;
  uint256 public start;
  uint256 public duration;

  bool public revocable;

  mapping (address => uint256) public released;
  mapping (address => bool) public revoked;

  /**
   * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
   * _beneficiary, gradually in a linear fashion until _start + _duration. By then all
   * of the balance will have vested.
   * @param _beneficiary address of the beneficiary to whom vested tokens are transferred
   * @param _cliff duration in seconds of the cliff in which tokens will begin to vest
   * @param _duration duration in seconds of the period in which the tokens will vest
   * @param _revocable whether the vesting is revocable or not
   */
  function TokenVesting(address _beneficiary, uint256 _start, uint256 _cliff, uint256 _duration, bool _revocable) {
    require(_beneficiary != 0x0);
    require(_cliff <= _duration);

    beneficiary = _beneficiary;
    revocable = _revocable;
    duration = _duration;
    cliff = _start + _cliff;
    start = _start;
  }

  /**
   * @notice Transfers vested tokens to beneficiary.
   * @param token ERC20 token which is being vested
   */
  function release(ERC20Basic token) {
    uint256 vested = vestedAmount(token);

    require(vested > 0);

    token.transfer(beneficiary, vested);

    released[token] = released[token].add(vested);

    Released(vested);
  }

  /**
   * @notice Allows the owner to revoke the vesting. Tokens already vested
   * remain in the contract, the rest are returned to the owner.
   * @param token ERC20 token which is being vested
   */
  function revoke(ERC20Basic token) onlyOwner {
    require(revocable);
    require(!revoked[token]);

    uint256 balance = token.balanceOf(this);

    uint256 vested = vestedAmount(token);
    uint256 vesting = balance - vested;

    revoked[token] = true;

    token.transfer(owner, vesting);

    Revoked();
  }

  /**
   * @dev Calculates the amount that has already vested but hasn't been released yet.
   * @param token ERC20 token which is being vested
   */
  function vestedAmount(ERC20Basic token) constant returns (uint256) {
    if (now < cliff) {
      return 0;
    } else if (now >= start + duration || revoked[token]) {
      return token.balanceOf(this);
    } else {
      uint256 currentBalance = token.balanceOf(this);
      uint256 totalBalance = currentBalance.add(released[token]);

      uint256 vested = totalBalance.mul(now - start).div(duration);
      uint256 unreleased = vested.sub(released[token]);

      // currentBalance can be 0 in case of vesting being revoked earlier.
      return Math.min256(currentBalance, unreleased);
    }
  }
}


Fix typo

Fix typo

pragma solidity ^0.4.15;

import "./vendor/grove/GroveLib.sol";

import "./IntervalTreeLib.sol";

contract IntervalTree {
  IntervalTreeLib.Tree tree;

  using IntervalTreeLib for IntervalTreeLib.Tree;

  function IntervalTree() {
  }

  function addInterval(uint begin, uint end, bytes32 data) {
    tree.addInterval(begin, end, data);
  }

  function numIntervals() constant returns (uint) {
    return tree.numIntervals;
  }

  function intervalsAt(uint point) constant returns (uint) {
    return tree.intervalsAt(point);
  }

  function intervalAt(uint point, uint offset)
    constant
    returns (uint begin, uint end, bytes32 data)
  {
    return tree.intervalAt(point, offset);
  }

}

pragma solidity ^0.4.15;

import "./vendor/grove/GroveLib.sol";

import "./IntervalTreeLib.sol";

contract IntervalTree {
  IntervalTreeLib.Tree tree;

  using IntervalTreeLib for IntervalTreeLib.Tree;

  function IntervalTree() {
  }

  function addInterval(uint begin, uint end, bytes32 data) {
    tree.addInterval(begin, end, data);
  }

  function numIntervals() constant returns (uint) {
    return tree.numIntervals;
  }

  function intervalsAt(uint point) constant returns (uint) {
    return tree.intervalsAt(point);
  }

  function intervalAt(uint point, uint offset)
    constant
    returns (uint begin, uint end, bytes32 data)
  {
    return tree.intervalAt(point, ooffset);
  }

}


ICO: added InvestmentAnalytics, small improvements

pragma solidity 0.4.15;

import './ownership/multiowned.sol';
import './crowdsale/FixedTimeBonuses.sol';
import './crowdsale/FundsRegistry.sol';
import './crowdsale/InvestmentAnalytics.sol';
import './security/ArgumentsChecker.sol';
import './STQToken.sol';
import 'zeppelin-solidity/contracts/ReentrancyGuard.sol';
import 'zeppelin-solidity/contracts/math/Math.sol';
import 'zeppelin-solidity/contracts/math/SafeMath.sol';

/// @title Storiqa ICO contract
contract STQCrowdsale is ArgumentsChecker, ReentrancyGuard, multiowned, InvestmentAnalytics {
    using Math for uint256;
    using SafeMath for uint256;
    using FixedTimeBonuses for FixedTimeBonuses.Data;

    enum IcoState { INIT, ICO, PAUSED, FAILED, SUCCEEDED }

    event StateChanged(IcoState _state);
    event FundTransfer(address backer, uint amount, bool isContribution);

    modifier requiresState(IcoState _state) {
        require(m_state == _state);
        _;
    }

    /// @dev triggers some state changes based on current time
    /// note: function body could be skipped!
    modifier timedStateChange() {
        if (IcoState.INIT == m_state && getCurrentTime() >= getStartTime())
            changeState(IcoState.ICO);

        if (IcoState.ICO == m_state && getCurrentTime() > getEndTime()) {
            finishICO();

            if (msg.value > 0)
                msg.sender.transfer(msg.value);
            // note that execution of further (but not preceding!) modifiers and functions ends here
        } else {
            _;
        }
    }

    /// @dev automatic check for unaccounted withdrawals
    modifier fundsChecker() {
        assert(m_state == IcoState.ICO);

        uint atTheBeginning = m_funds.balance;
        if (atTheBeginning < m_lastFundsAmount) {
            changeState(IcoState.PAUSED);
            if (msg.value > 0)
                msg.sender.transfer(msg.value); // we cant throw (have to save state), so refunding this way
            // note that execution of further (but not preceding!) modifiers and functions ends here
        } else {
            _;

            if (m_funds.balance < atTheBeginning) {
                changeState(IcoState.PAUSED);
            } else {
                m_lastFundsAmount = m_funds.balance;
            }
        }
    }

    // PUBLIC interface

    function STQCrowdsale(address[] _owners, address _token, address _funds)
        multiowned(_owners, 2)
        validAddress(_token)
        validAddress(_funds)
    {
        require(3 == _owners.length);

        m_token = STQToken(_token);
        m_funds = FundsRegistry(_funds);

        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (1 weeks), bonus: 30}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (2 weeks), bonus: 25}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (3 weeks), bonus: 20}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (4 weeks), bonus: 15}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (5 weeks), bonus: 10}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (8 weeks), bonus: 5}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: 1514246400, bonus: 0}));
        m_bonuses.validate(true);
    }

    // PUBLIC interface: payments

    // fallback function as a shortcut
    function() payable {
        require(0 == msg.data.length);
        buy();  // only internal call here!
    }

    /// @notice ICO participation
    function buy() public payable {     // dont mark as external!
        iaOnInvested(msg.sender, msg.value, false);
    }

    function iaOnInvested(address investor, uint payment, bool usingPaymentChannel)
        internal
        nonReentrant
        timedStateChange
        requiresState(IcoState.ICO)
        fundsChecker
    {
        require(payment >= c_MinInvestment);

        uint startingInvariant = this.balance.add(m_funds.balance);

        // checking for max cap
        uint fundsAllowed = getMaximumFunds().sub(getTotalInvested());
        assert(0 != fundsAllowed);  // in this case state must not be IcoState.ICO
        payment = fundsAllowed.min256(payment);
        uint256 change = msg.value.sub(payment);

        // issue tokens
        uint stq = calcSTQAmount(payment, usingPaymentChannel ? c_paymentChannelBonusPercent : 0);
        m_token.mint(investor, stq);

        // record payment
        m_funds.invested.value(payment)(investor);
        FundTransfer(investor, payment, true);

        // check if ICO must be closed early
        if (change > 0)
        {
            assert(getMaximumFunds() == getTotalInvested());
            finishICO();

            // send change
            investor.transfer(change);
            assert(startingInvariant == this.balance.add(m_funds.balance).add(change));
        }
        else
            assert(startingInvariant == this.balance.add(m_funds.balance));
    }

    // PUBLIC interface: owners: maintenance

    /// @notice pauses ICO
    function pause()
        external
        timedStateChange
        requiresState(IcoState.ICO)
        onlyowner
    {
        changeState(IcoState.PAUSED);
    }

    /// @notice resume paused ICO
    function unpause()
        external
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        changeState(IcoState.ICO);
        checkTime();
    }

    /// @notice consider paused ICO as failed
    function fail()
        external
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        changeState(IcoState.FAILED);
    }

    /// @notice In case we need to attach to existent token
    function setToken(address _token)
        external
        validAddress(_token)
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        m_token = STQToken(_token);
    }

    /// @notice In case we need to attach to existent funds
    function setFundsRegistry(address _funds)
        external
        validAddress(_funds)
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        m_funds = FundsRegistry(_funds);
    }

    /// @notice explicit trigger for timed state changes
    function checkTime()
        public
        timedStateChange
        onlyowner
    {
    }

    function createMorePaymentChannels(uint limit) external onlyowner returns (uint) {
        return createMorePaymentChannelsInternal(limit);
    }

    // INTERNAL functions

    function finishICO() private {
        if (getTotalInvested() < getMinFunds())
            changeState(IcoState.FAILED);
        else
            changeState(IcoState.SUCCEEDED);
    }

    /// @dev performs only allowed state transitions
    function changeState(IcoState _newState) private {
        assert(m_state != _newState);

        if (IcoState.INIT == m_state) {        assert(IcoState.ICO == _newState); }
        else if (IcoState.ICO == m_state) {    assert(IcoState.PAUSED == _newState || IcoState.FAILED == _newState || IcoState.SUCCEEDED == _newState); }
        else if (IcoState.PAUSED == m_state) { assert(IcoState.ICO == _newState || IcoState.FAILED == _newState); }
        else assert(false);

        m_state = _newState;
        StateChanged(m_state);

        // this should be tightly linked
        if (IcoState.SUCCEEDED == m_state) {
            onSuccess();
        } else if (IcoState.FAILED == m_state) {
            onFailure();
        }
    }

    function onSuccess() private {
        // mint tokens for owners
        uint tokensPerOwner = m_token.totalSupply().mul(4).div(m_numOwners);
        for (uint i = 0; i < m_numOwners; i++)
            m_token.mint(getOwner(i), tokensPerOwner);

        m_funds.changeState(FundsRegistry.State.SUCCEEDED);
        m_funds.detachController();

        m_token.disableMinting();
        m_token.startCirculation();
        m_token.detachController();
    }

    function onFailure() private {
        m_funds.changeState(FundsRegistry.State.REFUNDING);
        m_funds.detachController();
    }

    function getLargePaymentBonus(uint payment) private constant returns (uint) {
        if (payment > 5000 ether) return 20;
        if (payment > 3000 ether) return 15;
        if (payment > 1000 ether) return 10;
        if (payment > 800 ether) return 8;
        if (payment > 500 ether) return 5;
        if (payment > 200 ether) return 2;
        return 0;
    }

    /// @dev calculates amount of STQ to which payer of _wei is entitled
    function calcSTQAmount(uint _wei, uint extraBonus) private constant returns (uint) {
        uint stq = _wei.mul(c_STQperETH);

        uint bonus = extraBonus.add(m_bonuses.getBonus(getCurrentTime())).add(getLargePaymentBonus(_wei));

        // apply bonus
        stq = stq.mul(bonus.add(100)).div(100);

        return stq;
    }

    /// @dev start time of the ICO, inclusive
    function getStartTime() private constant returns (uint) {
        return c_startTime;
    }

    /// @dev end time of the ICO, inclusive
    function getEndTime() private constant returns (uint) {
        return m_bonuses.getLastTime();
    }

    /// @dev to be overridden in tests
    function getCurrentTime() internal constant returns (uint) {
        return now;
    }

    /// @dev to be overridden in tests
    function getMinFunds() internal constant returns (uint) {
        return c_MinFunds;
    }

    /// @dev to be overridden in tests
    function getMaximumFunds() internal constant returns (uint) {
        return c_MaximumFunds;
    }

    /// @dev amount of investments during all crowdsales
    function getTotalInvested() internal constant returns (uint) {
        return m_funds.totalInvested().add(2468 ether /* FIXME update me */);
    }

    // FIELDS

    /// @notice starting exchange rate of STQ
    uint public constant c_STQperETH = 100000;

    /// @notice minimum investment
    uint public constant c_MinInvestment = 10 finney;

    /// @notice minimum investments to consider ICO as a success
    uint public constant c_MinFunds = 30000 ether;

    /// @notice maximum investments to be accepted during ICO
    uint public constant c_MaximumFunds = 90000 ether;

    /// @notice start time of the ICO
    uint public constant c_startTime = 1508889600;

    /// @notice authorised payment bonus
    uint public constant c_paymentChannelBonusPercent = 2;

    /// @notice timed bonuses
    FixedTimeBonuses.Data m_bonuses;

    /// @dev state of the ICO
    IcoState public m_state = IcoState.INIT;

    /// @dev contract responsible for token accounting
    STQToken public m_token;

    /// @dev contract responsible for investments accounting
    FundsRegistry public m_funds;

    /// @dev last recorded funds
    uint256 public m_lastFundsAmount;
}

pragma solidity 0.4.15;

import './ownership/multiowned.sol';
import './crowdsale/FixedTimeBonuses.sol';
import './crowdsale/FundsRegistry.sol';
import './security/ArgumentsChecker.sol';
import './STQToken.sol';
import 'zeppelin-solidity/contracts/ReentrancyGuard.sol';
import 'zeppelin-solidity/contracts/math/Math.sol';
import 'zeppelin-solidity/contracts/math/SafeMath.sol';

/// @title Storiqa ICO contract
contract STQCrowdsale is ArgumentsChecker, ReentrancyGuard, multiowned {
    using Math for uint256;
    using SafeMath for uint256;
    using FixedTimeBonuses for FixedTimeBonuses.Data;

    enum IcoState { INIT, ICO, PAUSED, FAILED, SUCCEEDED }

    event StateChanged(IcoState _state);
    event FundTransfer(address backer, uint amount, bool isContribution);

    modifier requiresState(IcoState _state) {
        require(m_state == _state);
        _;
    }

    /// @dev triggers some state changes based on current time
    /// note: function body could be skipped!
    modifier timedStateChange() {
        if (IcoState.INIT == m_state && getCurrentTime() >= getStartTime())
            changeState(IcoState.ICO);

        if (IcoState.ICO == m_state && getCurrentTime() > getEndTime()) {
            finishICO();

            if (msg.value > 0)
                msg.sender.transfer(msg.value);
            // note that execution of further (but not preceding!) modifiers and functions ends here
        } else {
            _;
        }
    }

    /// @dev automatic check for unaccounted withdrawals
    modifier fundsChecker() {
        assert(m_state == IcoState.ICO);

        uint atTheBeginning = m_funds.balance;
        if (atTheBeginning < m_lastFundsAmount) {
            changeState(IcoState.PAUSED);
            if (msg.value > 0)
                msg.sender.transfer(msg.value); // we cant throw (have to save state), so refunding this way
            // note that execution of further (but not preceding!) modifiers and functions ends here
        } else {
            _;

            if (m_funds.balance < atTheBeginning) {
                changeState(IcoState.PAUSED);
            } else {
                m_lastFundsAmount = m_funds.balance;
            }
        }
    }

    // PUBLIC interface

    function STQCrowdsale(address[] _owners, address _token, address _funds)
        multiowned(_owners, 2)
        validAddress(_token)
        validAddress(_funds)
    {
        require(3 == _owners.length);

        m_token = STQToken(_token);
        m_funds = FundsRegistry(_funds);

        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (1 weeks), bonus: 30}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (2 weeks), bonus: 25}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (3 weeks), bonus: 20}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (4 weeks), bonus: 15}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (5 weeks), bonus: 10}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (8 weeks), bonus: 5}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: 1514246400, bonus: 0}));
        m_bonuses.validate(true);
    }

    // PUBLIC interface: payments

    // fallback function as a shortcut
    function() payable {
        buy();  // only internal call here!
    }

    /// @notice ICO participation
    /// @return number of STQ tokens bought (with all decimal symbols)
    function buy()
        public
        payable
        nonReentrant
        timedStateChange
        requiresState(IcoState.ICO)
        fundsChecker
        returns (uint)
    {
        address investor = msg.sender;
        uint256 payment = msg.value;
        require(payment >= c_MinInvestment);

        uint startingInvariant = this.balance.add(m_funds.balance);

        // checking for max cap
        uint fundsAllowed = getMaximumFunds().sub(getTotalInvested());
        assert(0 != fundsAllowed);  // in this case state must not be IcoState.ICO
        payment = fundsAllowed.min256(payment);
        uint256 change = msg.value.sub(payment);

        // issue tokens
        uint stq = calcSTQAmount(payment);
        m_token.mint(investor, stq);

        // record payment
        m_funds.invested.value(payment)(investor);
        FundTransfer(investor, payment, true);

        // check if ICO must be closed early
        if (change > 0)
        {
            assert(getMaximumFunds() == getTotalInvested());
            finishICO();

            // send change
            investor.transfer(change);
            assert(startingInvariant == this.balance.add(m_funds.balance).add(change));
        }
        else
            assert(startingInvariant == this.balance.add(m_funds.balance));

        return stq;
    }

    // PUBLIC interface: owners: maintenance

    /// @notice pauses ICO
    function pause()
        external
        timedStateChange
        requiresState(IcoState.ICO)
        onlyowner
    {
        changeState(IcoState.PAUSED);
    }

    /// @notice resume paused ICO
    function unpause()
        external
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        changeState(IcoState.ICO);
        checkTime();
    }

    /// @notice consider paused ICO as failed
    function fail()
        external
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        changeState(IcoState.FAILED);
    }

    /// @notice In case we need to attach to existent token
    function setToken(address _token)
        external
        validAddress(_token)
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        m_token = STQToken(_token);
    }

    /// @notice In case we need to attach to existent funds
    function setFundsRegistry(address _funds)
        external
        validAddress(_funds)
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        m_funds = FundsRegistry(_funds);
    }

    /// @notice explicit trigger for timed state changes
    function checkTime()
        public
        timedStateChange
        onlyowner
    {
    }

    // INTERNAL functions

    function finishICO() private {
        if (getTotalInvested() < getMinFunds())
            changeState(IcoState.FAILED);
        else
            changeState(IcoState.SUCCEEDED);
    }

    /// @dev performs only allowed state transitions
    function changeState(IcoState _newState) private {
        assert(m_state != _newState);

        if (IcoState.INIT == m_state) {        assert(IcoState.ICO == _newState); }
        else if (IcoState.ICO == m_state) {    assert(IcoState.PAUSED == _newState || IcoState.FAILED == _newState || IcoState.SUCCEEDED == _newState); }
        else if (IcoState.PAUSED == m_state) { assert(IcoState.ICO == _newState || IcoState.FAILED == _newState); }
        else assert(false);

        m_state = _newState;
        StateChanged(m_state);

        // this should be tightly linked
        if (IcoState.SUCCEEDED == m_state) {
            onSuccess();
        } else if (IcoState.FAILED == m_state) {
            onFailure();
        }
    }

    function onSuccess() private {
        // mint tokens for owners
        uint tokensPerOwner = m_token.totalSupply().mul(4).div(m_numOwners);
        for (uint i = 0; i < m_numOwners; i++)
            m_token.mint(getOwner(i), tokensPerOwner);

        m_funds.changeState(FundsRegistry.State.SUCCEEDED);
        m_funds.detachController();

        m_token.disableMinting();
        m_token.startCirculation();
        m_token.detachController();
    }

    function onFailure() private {
        m_funds.changeState(FundsRegistry.State.REFUNDING);
        m_funds.detachController();
    }

    function getLargePaymentBonus(uint payment) private constant returns (uint) {
        if (payment > 5000 ether) return 20;
        if (payment > 3000 ether) return 15;
        if (payment > 1000 ether) return 10;
        if (payment > 800 ether) return 8;
        if (payment > 500 ether) return 5;
        if (payment > 200 ether) return 2;
        return 0;
    }

    /// @dev calculates amount of STQ to which payer of _wei is entitled
    function calcSTQAmount(uint _wei) private constant returns (uint) {
        uint stq = _wei.mul(c_STQperETH);

        uint bonus = m_bonuses.getBonus(getCurrentTime()).add(getLargePaymentBonus(_wei));

        // apply bonus
        stq = stq.mul(bonus.add(100)).div(100);

        return stq;
    }

    /// @dev start time of the ICO, inclusive
    function getStartTime() private constant returns (uint) {
        return c_startTime;
    }

    /// @dev end time of the ICO, inclusive
    function getEndTime() private constant returns (uint) {
        return m_bonuses.getLastTime();
    }

    /// @dev to be overridden in tests
    function getCurrentTime() internal constant returns (uint) {
        return now;
    }

    /// @dev to be overridden in tests
    function getMinFunds() internal constant returns (uint) {
        return c_MinFunds;
    }

    /// @dev to be overridden in tests
    function getMaximumFunds() internal constant returns (uint) {
        return c_MaximumFunds;
    }

    /// @dev amount of investments during all crowdsales
    function getTotalInvested() internal constant returns (uint) {
        return (2468 ether /* FIXME update me */).add(m_funds.totalInvested());
    }

    // FIELDS

    /// @notice starting exchange rate of STQ
    uint public constant c_STQperETH = 100000;

    /// @notice minimum investment
    uint public constant c_MinInvestment = 10 finney;

    /// @notice minimum investments to consider ICO as a success
    uint public constant c_MinFunds = 30000 ether;

    /// @notice maximum investments to be accepted during ICO
    uint public constant c_MaximumFunds = 90000 ether;

    /// @notice start time of the ICO
    uint public constant c_startTime = 1508889600;

    /// @notice timed bonuses
    FixedTimeBonuses.Data m_bonuses;

    /// @dev state of the ICO
    IcoState public m_state = IcoState.INIT;

    /// @dev contract responsible for token accounting
    STQToken public m_token;

    /// @dev contract responsible for investments accounting
    FundsRegistry public m_funds;

    /// @dev last recorded funds
    uint256 public m_lastFundsAmount;
}


uint256 can't be < 0

uint256 can't be < 0

contract DaoChallenge
{
	modifier noEther() {if (msg.value > 0) throw; _}

	modifier onlyOwner() {if (owner != msg.sender) throw; _}

	event notifySellToken(uint256 n, address buyer);
	event notifyRefundToken(uint256 n, address tokenHolder);
	event notifyTerminate(uint256 finalBalance);

	/* This creates an array with all balances */
  mapping (address => uint256) public tokenBalanceOf;

	uint256 constant tokenPrice = 1000000000000000; // 1 finney

	// Owner of the challenge; a real DAO doesn't an owner.
	address owner;

	function sendOrThrow(address destination, uint256 amount) {
		bool result = destination.send(amount);
		if (!result) {
			throw;
		}
	}

	function DaoChallenge () {
		owner = msg.sender; // Owner of the challenge. Don't use this in a real DAO.
	}

	function () {
		address sender = msg.sender;
		if(tokenBalanceOf[sender] != 0) {
			throw;
		}
		tokenBalanceOf[sender] = msg.value / tokenPrice; // rounded down
		notifySellToken(tokenBalanceOf[sender], sender);
	}

	function refund() noEther {
		address sender = msg.sender;
		uint256 tokenBalance = tokenBalanceOf[sender];
		if (tokenBalance == 0) { throw; }
		tokenBalanceOf[sender] = 0;
		sendOrThrow(sender, tokenBalance * tokenPrice);
		notifyRefundToken(tokenBalance, sender);
	}

	// The owner of the challenge can terminate it. Don't use this in a real DAO.
	function terminate() noEther onlyOwner {
		notifyTerminate(this.balance);
		suicide(owner);
	}
}

contract DaoChallenge
{
	modifier noEther() {if (msg.value > 0) throw; _}

	modifier onlyOwner() {if (owner != msg.sender) throw; _}

	event notifySellToken(uint256 n, address buyer);
	event notifyRefundToken(uint256 n, address tokenHolder);
	event notifyTerminate(uint256 finalBalance);

	/* This creates an array with all balances */
  mapping (address => uint256) public tokenBalanceOf;

	uint256 constant tokenPrice = 1000000000000000; // 1 finney

	// Owner of the challenge; a real DAO doesn't an owner.
	address owner;

	function sendOrThrow(address destination, uint256 amount) {
		bool result = destination.send(amount);
		if (!result) {
			throw;
		}
	}

	function DaoChallenge () {
		owner = msg.sender; // Owner of the challenge. Don't use this in a real DAO.
	}

	function () {
		address sender = msg.sender;
		if(tokenBalanceOf[sender] != 0) {
			throw;
		}
		tokenBalanceOf[sender] = msg.value / tokenPrice; // rounded down
		notifySellToken(tokenBalanceOf[sender], sender);
	}

	function refund() noEther {
		address sender = msg.sender;
		uint256 tokenBalance = tokenBalanceOf[sender];
		if (tokenBalance <= 0) { throw; }
		tokenBalanceOf[sender] = 0;
		sendOrThrow(sender, tokenBalance * tokenPrice);
		notifyRefundToken(tokenBalance, sender);
	}

	// The owner of the challenge can terminate it. Don't use this in a real DAO.
	function terminate() noEther onlyOwner {
		notifyTerminate(this.balance);
		suicide(owner);
	}
}


remove token dependency from auction

remove token dependency from auction

pragma solidity 0.4.11;

/// @title Abstract Mint contract - Functions to be implemented by Mint contracts.
/// FIXME: is it necessary to provide the full interface?

contract Mint {
    function registerMintingRight(address eligible, uint num, uint startTime, uint endTime) returns (bool);
    function mintable(address account) returns (uint);
    function maxMintable() returns (uint);
    function isReady() returns (bool);
    function addCollateral() returns (bool);
}

/// @title Dutch auction contract - distribution of Raiden token Minting rights using an auction
/// @author Heiko, also credits to team Gnosis!
/// This is a variation of the Gnosis model. The price and number of mintable tokens are fixed.
/// Bidders bid for mining rights and compete on the dimension of the their max acceptable minting period.
/// The result of the auctinon are minting rights.
contract DutchAuction {

    /*
     *  Events
     */
    event BidSubmission(address indexed sender, uint256 amount);

    /*
     *  Storage
     */
    Token public token;
    Mint public mint;
    address public owner;
    uint public maxTokensAvailable;
    uint public waitingPeriod;
    uint public collateralCeiling; // max total accepted ETH collateral
    uint public collateralFactor; // tokens mintable per collateral (wei), i.e. 1/price
    uint public minCollateralPerBidder; // minimum collateral a bidder must offer
    uint public maxCollateralFractionPerBidder; // limits the number of tokens a bidder can have
    uint public totalCollateralReceived;
    uint public mintingPeriodFactor;
    uint public mintingPeriodDevisorConstant;
    uint public finalMintingPeriod; // result of the auction is a
    uint public startBlock; // block the auction starts
    uint public endTime; // time the auction ends at latest

    mapping (address => uint) public bids;

    /*
     *  Enums
     */
    enum Stages {
        AuctionDeployed,
        AuctionSetUp,
        AuctionStarted,
        AuctionEnded,
        TradingStarted
    }
    Stages public stage;

    /*
     *  Modifiers
     */
    modifier atStage(Stages _stage) {
        assert(stage == _stage);
        _;
    }

    modifier isOwner() {
        assert(msg.sender == owner);
        _;
    }

    modifier isValidPayload() {
        assert(msg.data.length == 4 || msg.data.length == 36);
        _;
    }

    modifier timedTransitions() {
        if (stage == Stages.AuctionStarted && (now > endTime || totalCollateralReceived == collateralCeiling))
            finalizeAuction();
        if (stage == Stages.AuctionEnded && now > endTime + waitingPeriod)
            stage = Stages.TradingStarted;
        _;
    }

    /*
     *  Public functions
     */
    /// @dev Contract constructor function sets owner.
    /// @param _collateralCeiling Auction collateralCeiling.
    /// @param _collateralFactor Auction price factor.
    function DutchAuction(uint _collateralCeiling,
                          uint _collateralFactor,
                          uint _maxTokensAvailable
                          uint _minCollateralPerBidder,
                          uint _maxCollateralFractionPercentPerBidder,
                          uint _mintingPeriodFactor,
                          uint _mintingPeriodDevisorConstant,
                          uint _waitingPeriod)
        public
    {
        owner = msg.sender;
        assert(_collateralCeiling && _collateralFactor);
        collateralCeiling = _collateralCeiling;
        collateralFactor = _collateralFactor;
        assert(_maxTokensAvailable);
        maxTokensAvailable = _maxTokensAvailable;
        assert(_minCollateralPerBidder)
        minCollateralPerBidder = _minCollateralPerBidder;
        assert(0 < _maxCollateralFractionPerBidder <=100);
        maxCollateralFractionPerBidder = _maxCollateralFractionPercentPerBidder;
        assert(_mintingPeriodFactor && _mintingPeriodDevisorConstant);
        mintingPeriodFactor = _mintingPeriodFactor;
        mintingPeriodDevisorConstant = _mintingPeriodDevisorConstant;
        waitingPeriod = _waitingPeriod;
        stage = Stages.AuctionDeployed;
    }

    /// @dev Setup function sets external contracts' addresses.
    /// @param _token the token address.
    function setup(address _mint)
        public
        isOwner
        atStage(Stages.AuctionDeployed)
    {
        // register mint
        assert(_mint);
        mint = Mint(_mint);
        assert(mint.isReady());
        assert(mint.maxMintable() - mint.totalMintingRightsGranted() >= maxTokensAvailable);
        stage = Stages.AuctionSetUp;
    }

    /// @dev Changes auction collateralCeiling and start price factor before auction is started.
    /// @param _collateralCeiling Updated auction collateralCeiling.
    /// @param _collateralFactor Updated start price factor.
    function changeSettings(uint _collateralCeiling, uint _collateralFactor)
        public
        idOwner
        atStage(Stages.AuctionSetUp)
    {
        collateralCeiling = _collateralCeiling;
        collateralFactor = _collateralFactor;
    }

    /// @dev Starts auction and sets startBlock.
    function startAuction()
        public
        isOwner
        atStage(Stages.AuctionSetUp)
    {
        stage = Stages.AuctionStarted;
        startBlock = block.number;
    }

    /// @dev Returns correct stage, even if a function with timedTransitions modifier has not yet been called yet.
    /// @return Returns current auction stage.
    function updateStage()
        public
        timedTransitions
        returns (Stages)
    {
        return stage;
    }

    /// @dev Allows to send a bid to the auction.
    /// @param bidder Bid will be assigned to this address if set.
    function bid(address bidder)
        public
        payable
        isValidPayload
        timedTransitions
        atStage(Stages.AuctionStarted)
        returns (uint amount)
    {
        // If a bid is done on behalf of a user via ShapeShift, the bidder address is set.
        if (bidder == 0)
            bidder = msg.sender;

        // enforce percentage per bidder limit
        uint maxWeiAccepted = collateralCeiling * maxCollateralFractionPercentPerBidder / 100;
        maxWeiAccepted -= bids[bidder]; // take in to account previously sent wei

        // enforce total collateral limit
        maxWeiAccepted = min(maxWeiAccepted, collateralCeiling - totalCollateralReceived);

        uint numWei = msg.value;

        // refund non acceptable wei
        if (numWei > maxWeiAccepted) {
            numWei = maxWeiAccepted;
            // Send change back to bidder address. In case of a ShapeShift bid the user receives the change back directly.
            assert(msg.value >= numWei);
            uint refund = msg.value - numWei
            assert(bidder.send(refund));
        }

        // register bid
        assert(numWei>0);
        bids[bidder] += numWei;
        BidSubmission(bidder, numWei);

        // enforce minimum required collateral per bidder, while allowing to add amounts later
        assert(bids[bidder] > minCollateralPerBidder);
        totalCollateralReceived += numWei;
        assert(totalCollateralReceived <= collateralCeiling);
        assert(totalCollateralReceived * collateralFactor <= maxTokensAvailable);

        // finalize if full
        if (totalCollateralReceived == collateralCeiling)
            // When maxWei is equal to the big numWei the auction is ended and finalizeAuction is triggered.
            finalizeAuction();
    }

    // mintingPeriodFactor: 10_000_000, mintingPeriodDevisorConstant: 1_000
    // starts with 27yrs, 4.5yrs @24hs, 2.4yrs @48hrs, 1.5yrs @72hrs
    function calcMintingPeriod(uint elapsedBlocks)
        constant
        public
        returns (uint)
        {
            return mintingPeriodFactor / (elapsedBlocks + mintingPeriodDevisorConstant);
        }

    function currentMintingPeriod()
        constant
        public
        atStage(Stage.AuctionStarted)
        returns (uint)
        {
            return calcMintingPeriod(block.number - startBlock);
        }

    function finalizeAuction()
        private
    {
        stage = Stages.AuctionEnded;
        endTime = now;

        // register mintingPeriod for all successful bidders
        uint elapsed = block.number - startBlock;
        finalMintingPeriod = calcMintingPeriod(elapsed);

        // Transfer funding to collateralize the token
        assert(mint.addCollateral.value(this.value)()); // FIXME double check
    }

    /// @dev registers minting rights for bidder after auction with the Mint
    /// @param receiver MintingRighhts will be assigned to this address if set
    function registerMintingRights(address receiver)
        public
        isValidPayload
        timedTransitions
        atStage(Stages.TradingStarted)
    {
        if (receiver == 0)
            receiver = msg.sender;
        uint tokenCount = bids[receiver] * collateralFactor;
        assert(tokenCount>0);
        bids[receiver] = 0;
        assert(mint.registerMintingRight(receiver, tokenCount, endTime, endTime + finalMintingPeriod));
    }

}

pragma solidity 0.4.11;

/// @title Abstract token contracts - Functions to be implemented by token contracts.
/// FIXME: is it necessary to provide the full interface?
contract Token {
    function addCollateral() returns (bool success);
    // This is not an abstract function, because solc won't recognize generated getter functions for public variables as functions.
    function totalSupply() constant returns (uint256 supply) {}
    function maxSupply() constant returns (uint256 supply) {}
}

contract Mint {
    function registerMintingRight(address eligible, uint num, uint startTime, uint endTime) returns (bool);
    function mintable(address account) returns (uint);
    function maxMintable() returns (uint);
    function isReady() returns (bool);
    function addCollateral() returns (bool);
}

/// @title Dutch auction contract - distribution of Raiden token Minting rights using an auction
/// @author Heiko, also credits to team Gnosis!
/// This is a variation of the Gnosis model. The price and number of mintable tokens are fixed.
/// Bidders bid for mining rights and compete on the dimension of the their max acceptable minting period.
/// The result of the auctinon are minting rights.
contract DutchAuction {

    /*
     *  Events
     */
    event BidSubmission(address indexed sender, uint256 amount);

    /*
     *  Storage
     */
    Token public token;
    Mint public mint;
    address public owner;
    uint public maxTokensAvailable;
    uint public waitingPeriod;
    uint public collateralCeiling; // max total accepted ETH collateral
    uint public collateralFactor; // tokens mintable per collateral (wei), i.e. 1/price
    uint public minCollateralPerBidder; // minimum collateral a bidder must offer
    uint public maxCollateralFractionPerBidder; // limits the number of tokens a bidder can have
    uint public totalCollateralReceived;
    uint public mintingPeriodFactor;
    uint public mintingPeriodDevisorConstant;
    uint public finalMintingPeriod; // result of the auction is a
    uint public startBlock; // block the auction starts
    uint public endTime; // time the auction ends at latest

    mapping (address => uint) public bids;

    /*
     *  Enums
     */
    enum Stages {
        AuctionDeployed,
        AuctionSetUp,
        AuctionStarted,
        AuctionEnded,
        TradingStarted
    }
    Stages public stage;

    /*
     *  Modifiers
     */
    modifier atStage(Stages _stage) {
        assert(stage == _stage);
        _;
    }

    modifier isOwner() {
        assert(msg.sender == owner);
        _;
    }

    modifier isValidPayload() {
        assert(msg.data.length == 4 || msg.data.length == 36);
        _;
    }

    modifier timedTransitions() {
        if (stage == Stages.AuctionStarted && (now > endTime || totalCollateralReceived == collateralCeiling))
            finalizeAuction();
        if (stage == Stages.AuctionEnded && now > endTime + waitingPeriod)
            stage = Stages.TradingStarted;
        _;
    }

    /*
     *  Public functions
     */
    /// @dev Contract constructor function sets owner.
    /// @param _collateralCeiling Auction collateralCeiling.
    /// @param _collateralFactor Auction price factor.
    function DutchAuction(uint _collateralCeiling,
                          uint _collateralFactor,
                          uint _maxTokensAvailable
                          uint _minCollateralPerBidder,
                          uint _maxCollateralFractionPercentPerBidder,
                          uint _mintingPeriodFactor,
                          uint _mintingPeriodDevisorConstant,
                          uint _waitingPeriod)
        public
    {
        owner = msg.sender;
        assert(_collateralCeiling && _collateralFactor);
        collateralCeiling = _collateralCeiling;
        collateralFactor = _collateralFactor;
        assert(_maxTokensAvailable);
        maxTokensAvailable = _maxTokensAvailable;
        assert(_minCollateralPerBidder)
        minCollateralPerBidder = _minCollateralPerBidder;
        assert(0 < _maxCollateralFractionPerBidder <=100);
        maxCollateralFractionPerBidder = _maxCollateralFractionPercentPerBidder;
        assert(_mintingPeriodFactor && _mintingPeriodDevisorConstant);
        mintingPeriodFactor = _mintingPeriodFactor;
        mintingPeriodDevisorConstant = _mintingPeriodDevisorConstant;
        waitingPeriod = _waitingPeriod;
        stage = Stages.AuctionDeployed;
    }

    /// @dev Setup function sets external contracts' addresses.
    /// @param _token the token address.
    function setup(address _token, address _mint)
        public
        isOwner
        atStage(Stages.AuctionDeployed)
    {
        // register token
        assert(_token);
        token = Token(_token);
        // Validate token supply
        assert(token.totalSupply() + maxTokensAvailable <= token.maxSupply());

        // register mint
        assert(_mint);
        mint = Mint(_mint);
        assert(mint.isReady());
        assert(mint.maxMintable() - mint.totalMintingRightsGranted() >= maxTokensAvailable);
        assert(mint.maxMintable() <= token.maxSupply() - token.totalSupply());

        stage = Stages.AuctionSetUp;
    }

    /// @dev Changes auction collateralCeiling and start price factor before auction is started.
    /// @param _collateralCeiling Updated auction collateralCeiling.
    /// @param _collateralFactor Updated start price factor.
    function changeSettings(uint _collateralCeiling, uint _collateralFactor)
        public
        idOwner
        atStage(Stages.AuctionSetUp)
    {
        collateralCeiling = _collateralCeiling;
        collateralFactor = _collateralFactor;
    }

    /// @dev Starts auction and sets startBlock.
    function startAuction()
        public
        isOwner
        atStage(Stages.AuctionSetUp)
    {
        stage = Stages.AuctionStarted;
        startBlock = block.number;
    }

    /// @dev Returns correct stage, even if a function with timedTransitions modifier has not yet been called yet.
    /// @return Returns current auction stage.
    function updateStage()
        public
        timedTransitions
        returns (Stages)
    {
        return stage;
    }

    /// @dev Allows to send a bid to the auction.
    /// @param bidder Bid will be assigned to this address if set.
    function bid(address bidder)
        public
        payable
        isValidPayload
        timedTransitions
        atStage(Stages.AuctionStarted)
        returns (uint amount)
    {
        // If a bid is done on behalf of a user via ShapeShift, the bidder address is set.
        if (bidder == 0)
            bidder = msg.sender;

        // enforce percentage per bidder limit
        uint maxWeiAccepted = collateralCeiling * maxCollateralFractionPercentPerBidder / 100;
        maxWeiAccepted -= bids[bidder]; // take in to account previously sent wei

        // enforce total collateral limit
        maxWeiAccepted = min(maxWeiAccepted, collateralCeiling - totalCollateralReceived);

        uint numWei = msg.value;

        // refund non acceptable wei
        if (numWei > maxWeiAccepted) {
            numWei = maxWeiAccepted;
            // Send change back to bidder address. In case of a ShapeShift bid the user receives the change back directly.
            assert(msg.value >= numWei);
            uint refund = msg.value - numWei
            assert(bidder.send(refund));
        }

        // register bid
        assert(numWei>0);
        bids[bidder] += numWei;
        BidSubmission(bidder, numWei);

        // enforce minimum required collateral per bidder, while allowing to add amounts later
        assert(bids[bidder] > minCollateralPerBidder);
        totalCollateralReceived += numWei;
        assert(totalCollateralReceived <= collateralCeiling);
        assert(totalCollateralReceived * collateralFactor <= maxTokensAvailable);

        // finalize if full
        if (totalCollateralReceived == collateralCeiling)
            // When maxWei is equal to the big numWei the auction is ended and finalizeAuction is triggered.
            finalizeAuction();
    }

    // mintingPeriodFactor: 10_000_000, mintingPeriodDevisorConstant: 1_000
    // starts with 27yrs, 4.5yrs @24hs, 2.4yrs @48hrs, 1.5yrs @72hrs
    function calcMintingPeriod(uint elapsedBlocks)
        constant
        public
        returns (uint)
        {
            return mintingPeriodFactor / (elapsedBlocks + mintingPeriodDevisorConstant);
        }

    function currentMintingPeriod()
        constant
        public
        atStage(Stage.AuctionStarted)
        returns (uint)
        {
            return calcMintingPeriod(block.number - startBlock);
        }

    function finalizeAuction()
        private
    {
        stage = Stages.AuctionEnded;
        endTime = now;

        // register mintingPeriod for all successful bidders
        uint elapsed = block.number - startBlock;
        finalMintingPeriod = calcMintingPeriod(elapsed);

        // Transfer funding to collateralize the token
        assert(mint.addCollateral.value(this.value)()); // FIXME double check
    }

    /// @dev registers minting rights for bidder after auction with the Mint
    /// @param receiver MintingRighhts will be assigned to this address if set
    function registerMintingRights(address receiver)
        public
        isValidPayload
        timedTransitions
        atStage(Stages.TradingStarted)
    {
        if (receiver == 0)
            receiver = msg.sender;
        uint tokenCount = bids[receiver] * collateralFactor;
        assert(tokenCount>0);
        bids[receiver] = 0;
        assert(mint.registerMintingRight(receiver, tokenCount, endTime, endTime + finalMintingPeriod));
    }

}