forcing constructor to have enough balance to pay for needed oracle queries.

/*
    Copyright 2017 Phillip A. Elsasser

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

pragma solidity ^0.4.0;

import "./Creatable.sol";
import "./Oraclize/oraclizeAPI.sol";

//TODO: fix style issues
//      add accounting for users and positions
//      how to hold ether for needed gas
//      how to hold collateral pool
//      add failsafe for pool distribution.
contract MarketContract is Creatable, usingOraclize  {

    // constants
    string public CONTRACT_NAME;
    address public BASE_TOKEN;
    uint public PRICE_CAP;
    uint public PRICE_FLOOR;
    uint public PRICE_DECIMAL_PLACES;   // how to convert the pricing from decimal format (if valid) to integer
    uint public EXPIRATION;
    string public ORACLE_DATA_SOURCE;
    string public ORACLE_QUERY;
    uint public ORACLE_QUERY_REPEAT;
    uint8 public BUY_SIDE = 0;
    uint8 public SELL_SIDE = 1;

    // state variables
    string public lastPriceQueryResult;
    uint public lastPrice;
    bool public isExpired;
    mapping(bytes32 => bool) validQueryIDs;

    // how to map user to position?
    event NewOracleQuery(string description);
    event UpdatedLastPrice(string price);
    event ContractSettled();

    struct Order {
        address maker;
        address taker;
        uint qty;
        uint price;
        uint8 makerSide;
        uint expirationTimeStamp;
        bytes32 orderHash;
    }

    function MarketContract(
        string contractName,
        address baseToken,
        string oracleDataSource,
        string oracleQuery,
        uint oracleQueryRepeatSeconds,
        uint floorPrice,
        uint capPrice,
        uint priceDecimalPlaces,
        uint daysToExpiration) payable {

        require(capPrice > floorPrice);
        oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
        CONTRACT_NAME = contractName;
        BASE_TOKEN = baseToken;
        PRICE_CAP = capPrice;
        PRICE_FLOOR = floorPrice;
        uint secondsToExpiration = daysToExpiration * 1 days;
        EXPIRATION = now + secondsToExpiration;
        ORACLE_DATA_SOURCE = oracleDataSource;
        ORACLE_QUERY = oracleQuery;
        ORACLE_QUERY_REPEAT = oracleQueryRepeatSeconds;
        PRICE_DECIMAL_PLACES = priceDecimalPlaces;
        require(checkSufficientStartingBalance(secondsToExpiration));
        queryOracle();  // schedules recursive calls to oracle
    }

    function __callback(bytes32 queryID, string result, bytes proof) {
        require(validQueryIDs[queryID]);
        require(msg.sender == oraclize_cbAddress());
        lastPriceQueryResult = result;
        lastPrice = parseInt(result, PRICE_DECIMAL_PLACES);
        UpdatedLastPrice(result);
        delete validQueryIDs[queryID];
        checkSettlement();
        if (!isExpired) {
            queryOracle();  // set up our next query
        }
    }

    function queryOracle() internal
    {
        if (oraclize_getPrice(ORACLE_DATA_SOURCE) > this.balance) {
            NewOracleQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee");
            lastPriceQueryResult = "FAILED"; //TODO: failsafe
        } else {
            NewOracleQuery("Oraclize query was sent, standing by for the answer..");
            bytes32 queryId = oraclize_query(ORACLE_QUERY_REPEAT, ORACLE_DATA_SOURCE, ORACLE_QUERY);
            validQueryIDs[queryId] = true;
        }
    }

    function checkSettlement() internal
    {
        if(isExpired)   // already expired.
            return;

        if(now > EXPIRATION) {
            isExpired = true;   // time based expiration has occurred.
        } else if(lastPrice >= PRICE_CAP || lastPrice <= PRICE_FLOOR) {
            isExpired = true;   // we have breached/touched our pricing bands
        }

        if(isExpired) {
            settleContract();
        }
    }

    function settleContract() internal
    {
        // TODO: build mechanism for distribution of collateral
        ContractSettled();
    }

    // for now lets require alot of padding for the settlement,
    function checkSufficientStartingBalance(uint secondsToExpiration) private returns (bool isSufficient) {
        uint approxQueriesRequired = secondsToExpiration / ORACLE_QUERY_REPEAT;
        uint approxGasRequired = oraclize_getPrice(ORACLE_DATA_SOURCE) * approxQueriesRequired;
        return this.balance > (approxGasRequired * 2);
    }
}

/*
    Copyright 2017 Phillip A. Elsasser

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

pragma solidity ^0.4.0;

import "./Creatable.sol";
import "./Oraclize/oraclizeAPI.sol";

//TODO: fix style issues
//      add accounting for users and positions
//      how to hold ether for needed gas
//      how to hold collateral pool
//      add failsafe for pool distribution.
contract MarketContract is Creatable, usingOraclize  {

    // constants
    string public CONTRACT_NAME;
    address public BASE_TOKEN;
    uint public PRICE_CAP;
    uint public PRICE_FLOOR;
    uint public PRICE_DECIMAL_PLACES;   // how to convert the pricing from decimal format (if valid) to integer
    uint public EXPIRATION;
    string public ORACLE_DATA_SOURCE;
    string public ORACLE_QUERY;
    uint public ORACLE_QUERY_REPEAT;
    uint8 public BUY_SIDE = 0;
    uint8 public SELL_SIDE = 1;

    // state variables
    string public lastPriceQueryResult;
    uint public lastPrice;
    bool public isExpired;
    mapping(bytes32 => bool) validQueryIDs;

    // how to map user to position?

    event NewOracleQuery(string description);
    event UpdatedLastPrice(string price);
    event ContractSettled();

    struct Order {
        address maker;
        address taker;
        uint qty;
        uint price;
        uint8 makerSide;
        uint expirationTimeStamp;
        bytes32 orderHash;
    }

    function MarketContract(
        string contractName,
        address baseToken,
        string oracleDataSource,
        string oracleQuery,
        uint oracleQueryRepeatSeconds,
        uint capPrice,
        uint floorPrice,
        uint priceDecimalPlaces,
        uint daysToExpiration) payable {

        require(capPrice > floorPrice);
        oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
        CONTRACT_NAME = contractName;
        BASE_TOKEN = baseToken;
        PRICE_CAP = capPrice;
        PRICE_FLOOR = floorPrice;
        EXPIRATION = now + daysToExpiration * 1 days;
        ORACLE_DATA_SOURCE = oracleDataSource;
        ORACLE_QUERY = oracleQuery;
        ORACLE_QUERY_REPEAT = oracleQueryRepeatSeconds;
        PRICE_DECIMAL_PLACES = priceDecimalPlaces;
        queryOracle();  // schedules recursive calls to oracle
    }

    function __callback(bytes32 queryID, string result, bytes proof) {
        require(validQueryIDs[queryID]);
        require(msg.sender == oraclize_cbAddress());
        lastPriceQueryResult = result;
        lastPrice = parseInt(result, PRICE_DECIMAL_PLACES);
        UpdatedLastPrice(result);
        delete validQueryIDs[queryID];
        checkSettlement();
        if (!isExpired) {
            queryOracle();  // set up our next query
        }
    }

    function queryOracle() internal
    {
        if (oraclize_getPrice(ORACLE_DATA_SOURCE) > this.balance) {
            NewOracleQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee");
            lastPriceQueryResult = "FAILED"; //TODO: failsafe
        } else {
            NewOracleQuery("Oraclize query was sent, standing by for the answer..");
            bytes32 queryId = oraclize_query(ORACLE_QUERY_REPEAT, ORACLE_DATA_SOURCE, ORACLE_QUERY);
            validQueryIDs[queryId] = true;
        }
    }

    function checkSettlement() internal
    {
        if(isExpired)   // already expired.
            return;

        if(now > EXPIRATION) {
            isExpired = true;   // time based expiration has occurred.
        } else if(lastPrice >= PRICE_CAP || lastPrice <= PRICE_FLOOR) {
            isExpired = true;   // we have breached/touched our pricing bands
        }

        if(isExpired) {
            settleContract();
        }
    }

    function settleContract() internal
    {
        // TODO: build mechanism for distribution of collateral
        ContractSettled();
    }
}


Include execution tracking events

Include execution tracking events

pragma solidity ^0.4.8;
import "./AbstractComputationService.sol";
import "./Judge.sol";

contract Arbiter {
  // Requests can have different status with a default of 0
  // status 100: request is created, no solutions are provided
  // status 200: request for computations send; awaiting results
  // status 300 + n: 0 + n results are in (i.e 301 := 1 result is in)
  // status 400: all results are in
  // status 500: solver and validators match
  // status 600: result send to requester
  // status 700 + n: solver and validators mismatch with n binary encoding of mismatches
  // e.g. status 729: 700 + 16 + 8 + 4 + 1 => verfier 0, 2, 3, 4 indicated a mismatch
  // status 800: dispute resolution started
  // status 801: dispute resolution state 1
  // status 901: dispute resolved; solver correct
  // status 902: dispute resolved; solver incorrect

  address public judge;

  struct Request {
    string input1;
    string input2;
    uint operation;
    uint256 computationId;
    address solver;
    address[] verifier;
    string resultSolver;
    string[6] resultVerifier;
    uint status;
    bool finished;
  }
  mapping(address => Request) public requests;
  mapping(uint256 => address) public computation;

  address[] public service;
  mapping(address => uint) internal serviceIndex;

  event newRequest(uint newRequest);
  event solverFound(address solverFound);
  event verifierFound(address verifierFound);
  event StatusChange(uint status_code);
  event newExecution(uint newExecution);
  event solverExecution(address solverExecution);
  event verifierExecution(address verifierExecution);

  // event thisIndex(uint thisIndex);
  // event step(uint thisStep);
  // event setLength(uint setLength);

  function enableService() {
    uint index;
    service.push(msg.sender);
    index = (service.length - 1);
    serviceIndex[msg.sender] = index;
  }

  function disableService() {
    uint index;
    index = serviceIndex[msg.sender];
    delete service[index];
    serviceIndex[msg.sender] = 0;

    // update service array and index mapping
    if (index < (service.length - 1)) {
      uint next_index;
      uint this_index;
      this_index = index;
      next_index = this_index + 1;

      while (this_index < (service.length - 1)) {
        service[this_index] = service[next_index];
        delete service[next_index];
        this_index++;
        next_index++;
      }
    }
  }

  function requestComputation(string _input1, string _input2, uint _operation, uint _numVerifiers) {
    // testEvent("Request computation started");
    address solver;
    address verifier;
    uint count = 0;
    uint check;
    uint index;
    uint length = service.length;
    address[] memory remainingService = new address[](length);

    // number of services for potential verifiers minus solver; maximum 6 verifiers
    if (_numVerifiers > (service.length - 1)) throw;
    if (_numVerifiers > 6) throw;

    remainingService = service;

    requests[msg.sender].input1 = _input1;
    requests[msg.sender].input2 = _input2;
    requests[msg.sender].operation = _operation;
    requests[msg.sender].computationId = rand(0, 2**64);

    newRequest(requests[msg.sender].computationId);

    // select a random solver from the list of computation services
    index = rand(0, length - 1);
    solver = remainingService[index];
    requests[msg.sender].solver = solver;
    solverFound(solver);

    for (uint i = index; i < length - 1; i++) {
      remainingService[i] = remainingService[i + 1];
    }
    // length-- is a workaround since memory arrays can NOT be resized
    length--;

    // select random verifiers from the list of computation services
    for (uint j = 0; j < _numVerifiers; j++) {
      index = rand(0, length - 1);
      verifier = remainingService[index];
      requests[msg.sender].verifier.push(verifier);
      verifierFound(verifier);

      for (uint k = index; k < length - 1; k++) {
        remainingService[k] = remainingService[k + 1];
      }
      length--;
    }

    // status 100: request is created, no solutions are provided
    requests[msg.sender].status = 100;
    StatusChange(requests[msg.sender].status);
  }

  function executeComputation() payable {
    newExecution(requests[msg.sender].computationId);
    // send computation request to the solver
    AbstractComputationService mySolver = AbstractComputationService(requests[msg.sender].solver);
    mySolver.compute(requests[msg.sender].input1, requests[msg.sender].input2, requests[msg.sender].operation, requests[msg.sender].computationId);
    solverExecution(requests[msg.sender].solver);

    // send computation request to all verifiers
    for (uint i = 0; i < requests[msg.sender].verifier.length; i++) {
      AbstractComputationService myVerifier = AbstractComputationService(requests[msg.sender].verifier[i]);
      myVerifier.compute(requests[msg.sender].input1, requests[msg.sender].input2, requests[msg.sender].operation, requests[msg.sender].computationId);
      verifierExecution(requests[msg.sender].verifier[i]);
    }

    // status 200: request for computations send; awaiting results
    requests[msg.sender].status = 200;
    StatusChange(requests[msg.sender].status);
  }

  function receiveResults(string _result, uint256 _computationId) {
    uint count = 0;
    // receive results from solvers and verifiers
    if (msg.sender == requests[computation[_computationId]].solver) {
      requests[computation[_computationId]].resultSolver = _result;
      count = 1;
    } else {
      for (uint i; i < requests[computation[_computationId]].verifier.length; i++) {
        if (msg.sender == requests[computation[_computationId]].verifier[i]) {
          requests[computation[_computationId]].resultVerifier[i] = _result;
          count = 1;
          break;
        }
      }
    }

    // status 300 + n: 0 + n results are in (i.e 301 := 1 result is in)
    if (requests[computation[_computationId]].status == 200) {
      requests[computation[_computationId]].status = 300 + count;
    } else {
      requests[computation[_computationId]].status += count;
    }

    if ((requests[computation[_computationId]].status - 300) == (1 + requests[computation[_computationId]].verifier.length)) {
      // status 400: all results are in
      requests[computation[_computationId]].status = 400;
    }

    StatusChange(requests[computation[_computationId]].status);
  }

  function compareResults() returns (uint) {
    if (requests[msg.sender].status != 400) throw;

    uint count = 0;

    for (uint i; i < requests[msg.sender].verifier.length; i++) {
      if (!(stringsEqual(requests[msg.sender].resultSolver,requests[msg.sender].resultVerifier[i]))) {
        count += 2**i;
      }
    }

    if (count == 0) {
      // status 500: solver and validators match
      requests[msg.sender].status = 500;
    } else {
      // status 700: solver and validators mismatch
      requests[msg.sender].status = 700 + count;
    }

    return requests[msg.sender].status;
    StatusChange(requests[msg.sender].status);
  }

  function requestIndex() {
    // get all verifiers that disagreed with the solver
    uint[] memory verifierIndex;
    uint count = requests[msg.sender].status - 700;
    uint insert;

    for (uint i = requests[msg.sender].verifier.length - 1; i >= 0; i--) {
      if (count >= 2**i) {
        insert = verifierIndex.length - 1;
        verifierIndex[insert] = i;
        count -= 2**i;
      }
    }

    // request an index in the result, which is different
    for (uint j = 0; j < verifierIndex.length; j++) {
      AbstractComputationService myVerifier = AbstractComputationService(requests[msg.sender].verifier[verifierIndex[j]]);
      myVerifier.provideIndex(requests[msg.sender].resultSolver, requests[msg.sender].computationId);
    }

    // status 800: dispute resolution started
    requests[msg.sender].status = 800;
    StatusChange(requests[msg.sender].status);
  }

  function receiveIndex(uint _index1, uint _index2, uint _operation, uint256 _computationId, bool _end) {
    // receives two coordinates
    uint result;
    bool solverCorrect;

    // check if solver and verifier value differ for given coordinates
    // this is just an integer check

    if (_end) {
      result = stringToUint(requests[computation[_computationId]].resultSolver);
      Judge myJudge = Judge(judge);
      solverCorrect = myJudge.resolveDispute(_index1, _index2, result, _operation);
      if (solverCorrect) {
        // status 901: dispute resolved; solver correct
        requests[computation[_computationId]].status = 901;
      } else {
        // status 902: dispute resolved; solver incorrect
        requests[computation[_computationId]].status = 902;
      }
    }
    StatusChange(requests[computation[_computationId]].status);
    // TODO: matrix check
  }

  function setJudge(address _judge) {
    judge = _judge;
  }

  function getStatus(address _requester) constant returns (uint status) {
    status = requests[_requester].status;
  }

  function stringToUint(string s) internal constant returns (uint result) {
    bytes memory b = bytes(s);
    uint i;
    result = 0;
    for (i = 0; i < b.length; i++) {
      uint c = uint(b[i]);
      if (c >= 48 && c <= 57) {
          result = result * 10 + (c - 48);
      }
    }
  }

  function stringsEqual(string _a, string _b) internal constant returns (bool) {
    bytes memory a = bytes(_a);
    bytes memory b = bytes(_b);
    if (a.length != b.length) return false;

    for (uint i = 0; i < a.length; i ++) {
      if (a[i] != b[i]) return false;
    }
    return true;
  }

  function rand(uint min, uint max) internal constant returns (uint256 random) {
    uint256 blockValue = uint256(block.blockhash(block.number-1));
    random = uint256(uint256(blockValue)%(min+max));
    return random;
  }
}

pragma solidity ^0.4.8;
import "./AbstractComputationService.sol";
import "./Judge.sol";

contract Arbiter {
  // Requests can have different status with a default of 0
  // status 100: request is created, no solutions are provided
  // status 200: request for computations send; awaiting results
  // status 300 + n: 0 + n results are in (i.e 301 := 1 result is in)
  // status 400: all results are in
  // status 500: solver and validators match
  // status 600: result send to requester
  // status 700 + n: solver and validators mismatch with n binary encoding of mismatches
  // e.g. status 729: 700 + 16 + 8 + 4 + 1 => verfier 0, 2, 3, 4 indicated a mismatch
  // status 800: dispute resolution started
  // status 801: dispute resolution state 1
  // status 901: dispute resolved; solver correct
  // status 902: dispute resolved; solver incorrect

  address public judge;

  struct Request {
    string input1;
    string input2;
    uint operation;
    uint256 computationId;
    address solver;
    address[] verifier;
    string resultSolver;
    string[6] resultVerifier;
    uint status;
    bool finished;
  }
  mapping(address => Request) public requests;
  mapping(uint256 => address) public computation;

  address[] public service;
  mapping(address => uint) internal serviceIndex;

  event newRequest(uint newRequest);
  event solverFound(address solverFound);
  event verifierFound(address verifierFound);
  event StatusChange(uint status_code);

  // event thisIndex(uint thisIndex);
  // event step(uint thisStep);
  // event setLength(uint setLength);

  function enableService() {
    uint index;
    service.push(msg.sender);
    index = (service.length - 1);
    serviceIndex[msg.sender] = index;
  }

  function disableService() {
    uint index;
    index = serviceIndex[msg.sender];
    delete service[index];
    serviceIndex[msg.sender] = 0;

    // update service array and index mapping
    if (index < (service.length - 1)) {
      uint next_index;
      uint this_index;
      this_index = index;
      next_index = this_index + 1;

      while (this_index < (service.length - 1)) {
        service[this_index] = service[next_index];
        delete service[next_index];
        this_index++;
        next_index++;
      }
    }
  }

  function requestComputation(string _input1, string _input2, uint _operation, uint _numVerifiers) {
    // testEvent("Request computation started");
    address solver;
    address verifier;
    uint count = 0;
    uint check;
    uint index;
    uint length = service.length;
    address[] memory remainingService = new address[](length);

    // number of services for potential verifiers minus solver; maximum 6 verifiers
    if (_numVerifiers > (service.length - 1)) throw;
    if (_numVerifiers > 6) throw;

    remainingService = service;

    requests[msg.sender].input1 = _input1;
    requests[msg.sender].input2 = _input2;
    requests[msg.sender].operation = _operation;
    requests[msg.sender].computationId = rand(0, 2**64);

    newRequest(requests[msg.sender].computationId);

    // select a random solver from the list of computation services
    index = rand(0, length - 1);
    solver = remainingService[index];
    requests[msg.sender].solver = solver;
    solverFound(solver);

    for (uint i = index; i < length - 1; i++) {
      remainingService[i] = remainingService[i + 1];
    }
    // length-- is a workaround since memory arrays can NOT be resized
    length--;

    // select random verifiers from the list of computation services
    for (uint j = 0; j < _numVerifiers; j++) {
      index = rand(0, length - 1);
      verifier = remainingService[index];
      requests[msg.sender].verifier.push(verifier);
      verifierFound(verifier);

      for (uint k = index; k < length - 1; k++) {
        remainingService[k] = remainingService[k + 1];
      }
      length--;
    }

    // status 100: request is created, no solutions are provided
    requests[msg.sender].status = 100;
    StatusChange(requests[msg.sender].status);
  }

  function executeComputation() payable {
    // send computation request to the solver
    AbstractComputationService mySolver = AbstractComputationService(requests[msg.sender].solver);
    mySolver.compute(requests[msg.sender].input1, requests[msg.sender].input2, requests[msg.sender].operation, requests[msg.sender].computationId);

    // send computation request to all verifiers
    for (uint i = 0; i < requests[msg.sender].verifier.length; i++) {
      AbstractComputationService myVerifier = AbstractComputationService(requests[msg.sender].verifier[i]);
        myVerifier.compute(requests[msg.sender].input1, requests[msg.sender].input2, requests[msg.sender].operation, requests[msg.sender].computationId);
    }

    // status 200: request for computations send; awaiting results
    requests[msg.sender].status = 200;
    StatusChange(requests[msg.sender].status);
  }

  function receiveResults(string _result, uint256 _computationId) {
    uint count = 0;
    // receive results from solvers and verifiers
    if (msg.sender == requests[computation[_computationId]].solver) {
      requests[computation[_computationId]].resultSolver = _result;
      count = 1;
    } else {
      for (uint i; i < requests[computation[_computationId]].verifier.length; i++) {
        if (msg.sender == requests[computation[_computationId]].verifier[i]) {
          requests[computation[_computationId]].resultVerifier[i] = _result;
          count = 1;
          break;
        }
      }
    }

    // status 300 + n: 0 + n results are in (i.e 301 := 1 result is in)
    if (requests[computation[_computationId]].status == 200) {
      requests[computation[_computationId]].status = 300 + count;
    } else {
      requests[computation[_computationId]].status += count;
    }

    if ((requests[computation[_computationId]].status - 300) == (1 + requests[computation[_computationId]].verifier.length)) {
      // status 400: all results are in
      requests[computation[_computationId]].status = 400;
    }

    StatusChange(requests[computation[_computationId]].status);
  }

  function compareResults() returns (uint) {
    if (requests[msg.sender].status != 400) throw;

    uint count = 0;

    for (uint i; i < requests[msg.sender].verifier.length; i++) {
      if (!(stringsEqual(requests[msg.sender].resultSolver,requests[msg.sender].resultVerifier[i]))) {
        count += 2**i;
      }
    }

    if (count == 0) {
      // status 500: solver and validators match
      requests[msg.sender].status = 500;
    } else {
      // status 700: solver and validators mismatch
      requests[msg.sender].status = 700 + count;
    }

    return requests[msg.sender].status;
    StatusChange(requests[msg.sender].status);
  }

  function requestIndex() {
    // get all verifiers that disagreed with the solver
    uint[] memory verifierIndex;
    uint count = requests[msg.sender].status - 700;
    uint insert;

    for (uint i = requests[msg.sender].verifier.length - 1; i >= 0; i--) {
      if (count >= 2**i) {
        insert = verifierIndex.length - 1;
        verifierIndex[insert] = i;
        count -= 2**i;
      }
    }

    // request an index in the result, which is different
    for (uint j = 0; j < verifierIndex.length; j++) {
      AbstractComputationService myVerifier = AbstractComputationService(requests[msg.sender].verifier[verifierIndex[j]]);
      myVerifier.provideIndex(requests[msg.sender].resultSolver, requests[msg.sender].computationId);
    }

    // status 800: dispute resolution started
    requests[msg.sender].status = 800;
    StatusChange(requests[msg.sender].status);
  }

  function receiveIndex(uint _index1, uint _index2, uint _operation, uint256 _computationId, bool _end) {
    // receives two coordinates
    uint result;
    bool solverCorrect;

    // check if solver and verifier value differ for given coordinates
    // this is just an integer check

    if (_end) {
      result = stringToUint(requests[computation[_computationId]].resultSolver);
      Judge myJudge = Judge(judge);
      solverCorrect = myJudge.resolveDispute(_index1, _index2, result, _operation);
      if (solverCorrect) {
        // status 901: dispute resolved; solver correct
        requests[computation[_computationId]].status = 901;
      } else {
        // status 902: dispute resolved; solver incorrect
        requests[computation[_computationId]].status = 902;
      }
    }
    StatusChange(requests[computation[_computationId]].status);
    // TODO: matrix check
  }

  function setJudge(address _judge) {
    judge = _judge;
  }

  function getStatus(address _requester) constant returns (uint status) {
    status = requests[_requester].status;
  }

  function stringToUint(string s) internal constant returns (uint result) {
    bytes memory b = bytes(s);
    uint i;
    result = 0;
    for (i = 0; i < b.length; i++) {
      uint c = uint(b[i]);
      if (c >= 48 && c <= 57) {
          result = result * 10 + (c - 48);
      }
    }
  }

  function stringsEqual(string _a, string _b) internal constant returns (bool) {
    bytes memory a = bytes(_a);
    bytes memory b = bytes(_b);
    if (a.length != b.length) return false;

    for (uint i = 0; i < a.length; i ++) {
      if (a[i] != b[i]) return false;
    }
    return true;
  }

  function rand(uint min, uint max) internal constant returns (uint256 random) {
    uint256 blockValue = uint256(block.blockhash(block.number-1));
    random = uint256(uint256(blockValue)%(min+max));
    return random;
  }
}


make Ownable transferrable

make Ownable transferrable

/*
 * Ownable
 * Base contract with an owner
 */
contract Ownable {
  address owner;

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

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

  function transfer(address newOwner) onlyOwner {
    owner = newOwner;
  }

}

/*
 * Ownable
 * Base contract with an owner
 */
contract Ownable {
  address owner;

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

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


Update interface & pragma

Update interface & pragma

pragma solidity ^0.4.18;

contract ContractProvider {
    function contracts(bytes32 contractName) public returns (address addr);
}

pragma solidity ^0.4.11;

contract ContractProvider {
    function contracts(bytes32 contractName) returns (address addr){}
}


Fixed bug in Vault Contract

Fixed bug in Vault Contract

pragma solidity ^0.4.6;
import "./Escapable.sol";

/*
    Copyright 2016, Jordi Baylina

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/// @title Vault Contract
/// @author Jordi Baylina
/// @notice This contract holds funds for Campaigns and automates payments. For
///  this iteration the funds will come straight from the Giveth Multisig as a
///  safety precaution, but once fully tested and optimized this contract will
///  be a safe place to store funds equipped with optional variable time delays
///  to allow for an optional escape hatch

/// @dev `Vault` is a higher level contract built off of the `Escapable`
///  contract that holds funds for Campaigns and automates payments.
contract Vault is Escapable {

    /// @dev `Payment` is a public structure that describes the details of
    ///  each payment making it easy to track the movement of funds
    ///  transparently
    struct Payment {
        string name;     // What is the purpose of this payment
        bytes32 reference;  // Reference of the payment.
        address spender;        // Who is sending the funds
        uint earliestPayTime;   // The earliest a payment can be made (Unix Time)
        bool canceled;         // If True then the payment has been canceled
        bool paid;              // If True then the payment has been paid
        address recipient;      // Who is receiving the funds
        uint amount;            // The amount of wei sent in the payment
        uint securityGuardDelay;// The seconds `securityGuard` can delay payment
    }

    Payment[] public authorizedPayments;

    address public securityGuard;
    uint public absoluteMinTimeLock;
    uint public timeLock;
    uint public maxSecurityGuardDelay;

    /// @dev The white list of approved addresses allowed to set up && receive
    ///  payments from this vault
    mapping (address => bool) public allowedSpenders;

    /// @dev The address assigned the role of `securityGuard` is the only
    ///  addresses that can call a function with this modifier
    modifier onlySecurityGuard { if (msg.sender != securityGuard) throw; _; }

    // @dev Events to make the payment movements easy to find on the blockchain
    event PaymentAuthorized(uint indexed idPayment, address indexed recipient, uint amount);
    event PaymentExecuted(uint indexed idPayment, address indexed recipient, uint amount);
    event PaymentCanceled(uint indexed idPayment);
    event EtherReceived(address indexed from, uint amount);
    event SpenderAuthorization(address indexed spender, bool authorized);

/////////
// Constructor
/////////

    /// @notice The Constructor creates the Vault on the blockchain
    /// @param _escapeHatchCaller The address of a trusted account or contract to
    ///  call `escapeHatch()` to send the ether in this contract to the
    ///  `escapeHatchDestination` it would be ideal if `escapeHatchCaller` cannot move
    ///  funds out of `escapeHatchDestination`
    /// @param _escapeHatchDestination The address of a safe location (usu a
    ///  Multisig) to send the ether held in this contract in an emergency
    /// @param _absoluteMinTimeLock The minimum number of seconds `timelock` can
    ///  be set to, if set to 0 the `owner` can remove the `timeLock` completely
    /// @param _timeLock Initial number of seconds that payments are delayed
    ///  after they are authorized (a security precaution)
    /// @param _securityGuard Address that will be able to delay the payments
    ///  beyond the initial timelock requirements; can be set to 0x0 to remove
    ///  the `securityGuard` functionality
    /// @param _maxSecurityGuardDelay The maximum number of seconds in total
    ///   that `securityGuard` can delay a payment so that the owner can cancel
    ///   the payment if needed
    function Vault(
        address _escapeHatchCaller,
        address _escapeHatchDestination,
        uint _absoluteMinTimeLock,
        uint _timeLock,
        address _securityGuard,
        uint _maxSecurityGuardDelay) Escapable(_escapeHatchCaller, _escapeHatchDestination)
    {
        absoluteMinTimeLock = _absoluteMinTimeLock;
        timeLock = _timeLock;
        securityGuard = _securityGuard;
        maxSecurityGuardDelay = _maxSecurityGuardDelay;
    }

/////////
// Helper functions
/////////

    /// @notice States the total number of authorized payments in this contract
    /// @return The number of payments ever authorized even if they were canceled
    function numberOfAuthorizedPayments() constant returns (uint) {
        return authorizedPayments.length;
    }

//////
// Receive Ether
//////

    /// @notice Called anytime ether is sent to the contract && creates an event
    /// to more easily track the incoming transactions
    function receiveEther() payable {
        if (msg.value <= 0) {
            throw;
        }
        EtherReceived(msg.sender, msg.value);
    }

    /// @notice The fall back function is called whenever ether is sent to this
    ///  contract
    function () payable {
        receiveEther();
    }

////////
// Spender Interface
////////
    /// @notice only `allowedSpenders[]` Creates a new `Payment`
    /// @param _name Brief description of the payment that is authorized
    /// @param _recipient Destination of the payment
    /// @param _amount Amount to be paid in wei
    /// @param _paymentDelay Number of seconds the payment is to be delayed, if
    ///  this value is below `timeLock` then the `timeLock` determines the delay
    /// @return The Payment ID number for the new authorized payment
    function authorizePayment(
        string _name,
        address _recipient,
        uint _amount,
        uint _paymentDelay
    ) returns(uint) {

        // Fail if you arent on the `allowedSpenders` white list
        if (!allowedSpenders[msg.sender] ) throw;
        uint idPayment = authorizedPayments.length;       // Unique Payment ID
        authorizedPayments.length++;

        // The following lines fill out the payment struct
        Payment p = authorizedPayments[idPayment];
        p.spender = msg.sender;

        // Overflow protection
        if (_paymentDelay > 10**18) throw;

        // Determines the earliest the recipient can receive payment (Unix time)
        p.earliestPayTime = _paymentDelay >= timeLock ?
                                now + _paymentDelay :
                                now + timeLock;
        p.recipient = _recipient;
        p.amount = _amount;
        p.name = _name;
        PaymentAuthorized(idPayment, p.recipient, p.amount);
        return idPayment;
    }

    /// @notice only `allowedSpenders[]` The recipient of a payment calls this
    ///  function to send themselves the ether after the `earliestPayTime` has
    ///  expired
    /// @param _idPayment The payment ID to be executed
    function collectAuthorizedPayment(uint _idPayment) {

        // Check that the `_idPayment` has been added to the payments struct
        if (_idPayment >= authorizedPayments.length) throw;

        Payment p = authorizedPayments[_idPayment];

        // Checking for reasons not to execute the payment
        if (msg.sender != p.recipient) throw;
        if (!allowedSpenders[p.spender]) throw;
        if (now < p.earliestPayTime) throw;
        if (p.canceled) throw;
        if (p.paid) throw;
        if (this.balance < p.amount || p.amount == 0) throw;

        p.paid = true; // Set the payment to being paid

        p.recipient.transfer(p.amount);

        PaymentExecuted(_idPayment, p.recipient, p.amount);
     }

/////////
// SecurityGuard Interface
/////////

    /// @notice `onlySecurityGuard` Delays a payment for a set number of seconds
    /// @param _idPayment ID of the payment to be delayed
    /// @param _delay The number of seconds to delay the payment
    function delayPayment(uint _idPayment, uint _delay) onlySecurityGuard {
        if (_idPayment >= authorizedPayments.length) throw;

        // Overflow test
        if (_delay > 10**18) throw;

        Payment p = authorizedPayments[_idPayment];

        if ((p.securityGuardDelay + _delay > maxSecurityGuardDelay) ||
            (p.paid) ||
            (p.canceled))
            throw;

        p.securityGuardDelay += _delay;
        p.earliestPayTime += _delay;
    }

////////
// Owner Interface
///////

    /// @notice `onlyOwner` Cancel a payment all together
    /// @param _idPayment ID of the payment to be canceled.
    function cancelPayment(uint _idPayment) onlyOwner {
        if (_idPayment >= authorizedPayments.length) throw;

        Payment p = authorizedPayments[_idPayment];

        if (p.canceled) throw;
        if (p.paid) throw;

        p.canceled = true;
        PaymentCanceled(_idPayment);
    }

    /// @notice `onlyOwner` Adds a spender to the `allowedSpenders[]` white list
    /// @param _spender The address of the contract being authorized/unauthorized
    /// @param _authorize `true` if authorizing and `false` if unauthorizing
    function authorizeSpender(address _spender, bool _authorize) onlyOwner {
        allowedSpenders[_spender] = _authorize;
        SpenderAuthorization(_spender, _authorize);
    }

    /// @notice `onlyOwner` Sets the address of `securityGuard`
    /// @param _newSecurityGuard Address of the new security guard
    function setSecurityGuard(address _newSecurityGuard) onlyOwner {
        securityGuard = _newSecurityGuard;
    }

    /// @notice `onlyOwner` Changes `timeLock`; the new `timeLock` cannot be
    ///  lower than `absoluteMinTimeLock`
    /// @param _newTimeLock Sets the new minimum default `timeLock` in seconds;
    ///  pending payments maintain their `earliestPayTime`
    function setTimelock(uint _newTimeLock) onlyOwner {
        if (_newTimeLock < absoluteMinTimeLock) throw;
        timeLock = _newTimeLock;
    }

    /// @notice `onlyOwner` Changes the maximum number of seconds
    /// `securityGuard` can delay a payment
    /// @param _maxSecurityGuardDelay The new maximum delay in seconds that
    ///  `securityGuard` can delay the payment's execution in total
    function setMaxSecurityGuardDelay(uint _maxSecurityGuardDelay) onlyOwner {
        maxSecurityGuardDelay = _maxSecurityGuardDelay;
    }
}

pragma solidity ^0.4.6;
import "./Escapable.sol";

/*
    Copyright 2016, Jordi Baylina

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/// @title Vault Contract
/// @author Jordi Baylina
/// @notice This contract holds funds for Campaigns and automates payments. For
///  this iteration the funds will come straight from the Giveth Multisig as a
///  safety precaution, but once fully tested and optimized this contract will
///  be a safe place to store funds equipped with optional variable time delays
///  to allow for an optional escape hatch

/// @dev `Vault` is a higher level contract built off of the `Escapable`
///  contract that holds funds for Campaigns and automates payments.
contract Vault is Escapable {

    /// @dev `Payment` is a public structure that describes the details of
    ///  each payment making it easy to track the movement of funds
    ///  transparently
    struct Payment {
        string name;     // What is the purpose of this payment
        bytes32 reference;  // Reference of the payment.
        address spender;        // Who is sending the funds
        uint earliestPayTime;   // The earliest a payment can be made (Unix Time)
        bool canceled;         // If True then the payment has been canceled
        bool paid;              // If True then the payment has been paid
        address recipient;      // Who is receiving the funds
        uint amount;            // The amount of wei sent in the payment
        uint securityGuardDelay;// The seconds `securityGuard` can delay payment
    }

    Payment[] public authorizedPayments;

    address public securityGuard;
    uint public absoluteMinTimeLock;
    uint public timeLock;
    uint public maxSecurityGuardDelay;

    /// @dev The white list of approved addresses allowed to set up && receive
    ///  payments from this vault
    mapping (address => bool) public allowedSpenders;

    /// @dev The address assigned the role of `securityGuard` is the only
    ///  addresses that can call a function with this modifier
    modifier onlySecurityGuard { if (msg.sender != securityGuard) throw; _; }

    // @dev Events to make the payment movements easy to find on the blockchain
    event PaymentAuthorized(uint indexed idPayment, address indexed recipient, uint amount);
    event PaymentExecuted(uint indexed idPayment, address indexed recipient, uint amount);
    event PaymentCanceled(uint indexed idPayment);
    event EtherReceived(address indexed from, uint amount);
    event SpenderAuthorization(address indexed spender, bool authorized);

/////////
// Constructor
/////////

    /// @notice The Constructor creates the Vault on the blockchain
    /// @param _escapeHatchCaller The address of a trusted account or contract to
    ///  call `escapeHatch()` to send the ether in this contract to the
    ///  `escapeHatchDestination` it would be ideal if `escapeHatchCaller` cannot move
    ///  funds out of `escapeHatchDestination`
    /// @param _escapeHatchDestination The address of a safe location (usu a
    ///  Multisig) to send the ether held in this contract in an emergency
    /// @param _absoluteMinTimeLock The minimum number of seconds `timelock` can
    ///  be set to, if set to 0 the `owner` can remove the `timeLock` completely
    /// @param _timeLock Initial number of seconds that payments are delayed
    ///  after they are authorized (a security precaution)
    /// @param _securityGuard Address that will be able to delay the payments
    ///  beyond the initial timelock requirements; can be set to 0x0 to remove
    ///  the `securityGuard` functionality
    /// @param _maxSecurityGuardDelay The maximum number of seconds in total
    ///   that `securityGuard` can delay a payment so that the owner can cancel
    ///   the payment if needed
    function Vault(
        address _escapeHatchCaller,
        address _escapeHatchDestination,
        uint _absoluteMinTimeLock,
        uint _timeLock,
        address _securityGuard,
        uint _maxSecurityGuardDelay) Escapable(_escapeHatchCaller, _escapeHatchDestination)
    {
        absoluteMinTimeLock = _absoluteMinTimeLock;
        timeLock = _timeLock;
        securityGuard = _securityGuard;
        maxSecurityGuardDelay = _maxSecurityGuardDelay;
    }

/////////
// Helper functions
/////////

    /// @notice States the total number of authorized payments in this contract
    /// @return The number of payments ever authorized even if they were canceled
    function numberOfAuthorizedPayments() constant returns (uint) {
        return authorizedPayments.length;
    }

//////
// Receive Ether
//////

    /// @notice Called anytime ether is sent to the contract && creates an event
    /// to more easily track the incoming transactions
    function receiveEther() payable {
        if (msg.value <= 0) {
            throw;
        }
        EtherReceived(msg.sender, msg.value);
    }

    /// @notice The fall back function is called whenever ether is sent to this
    ///  contract
    function () payable {
        receiveEther();
    }

////////
// Spender Interface
////////
    /// @notice only `allowedSpenders[]` Creates a new `Payment`
    /// @param _name Brief description of the payment that is authorized
    /// @param _recipient Destination of the payment
    /// @param _amount Amount to be paid in wei
    /// @param _paymentDelay Number of seconds the payment is to be delayed, if
    ///  this value is below `timeLock` then the `timeLock` determines the delay
    /// @return The Payment ID number for the new authorized payment
    function authorizePayment(
        string _name,
        address _recipient,
        uint _amount,
        uint _paymentDelay
    ) returns(uint) {

        // Fail if you arent on the `allowedSpenders` white list
        if (!allowedSpenders[msg.sender] ) throw;
        uint idPayment = authorizedPayments.length;       // Unique Payment ID
        authorizedPayments.length++;

        // The following lines fill out the payment struct
        Payment p = authorizedPayments[idPayment];
        p.spender = msg.sender;

        // Overflow protection
        if (_paymentDelay > 10**18) throw;

        // Determines the earliest the recipient can receive payment (Unix time)
        p.earliestPayTime = _paymentDelay >= timeLock ?
                                now + _paymentDelay :
                                now + timeLock;
        p.recipient = _recipient;
        p.amount = _amount;
        p.name = _name;
        PaymentAuthorized(idPayment, p.recipient, p.amount);
        return idPayment;
    }

    /// @notice only `allowedSpenders[]` The recipient of a payment calls this
    ///  function to send themselves the ether after the `earliestPayTime` has
    ///  expired
    /// @param _idPayment The payment ID to be executed
    function collectAuthorizedPayment(uint _idPayment) {

        // Check that the `_idPayment` has been added to the payments struct
        if (_idPayment >= authorizedPayments.length) throw;

        Payment p = authorizedPayments[_idPayment];

        // Checking for reasons not to execute the payment
        if (msg.sender != p.recipient) throw;
        if (!allowedSpenders[p.spender]) throw;
        if (now < p.earliestPayTime) throw;
        if (p.canceled) throw;
        if (p.paid) throw;
        if (this.balance < p.amount p.amount == 0) throw;

        p.paid = true; // Set the payment to being paid

        p.recipient.transfer(p.amount);

        PaymentExecuted(_idPayment, p.recipient, p.amount);
     }

/////////
// SecurityGuard Interface
/////////

    /// @notice `onlySecurityGuard` Delays a payment for a set number of seconds
    /// @param _idPayment ID of the payment to be delayed
    /// @param _delay The number of seconds to delay the payment
    function delayPayment(uint _idPayment, uint _delay) onlySecurityGuard {
        if (_idPayment >= authorizedPayments.length) throw;

        // Overflow test
        if (_delay > 10**18) throw;

        Payment p = authorizedPayments[_idPayment];

        if ((p.securityGuardDelay + _delay > maxSecurityGuardDelay) ||
            (p.paid) ||
            (p.canceled))
            throw;

        p.securityGuardDelay += _delay;
        p.earliestPayTime += _delay;
    }

////////
// Owner Interface
///////

    /// @notice `onlyOwner` Cancel a payment all together
    /// @param _idPayment ID of the payment to be canceled.
    function cancelPayment(uint _idPayment) onlyOwner {
        if (_idPayment >= authorizedPayments.length) throw;

        Payment p = authorizedPayments[_idPayment];

        if (p.canceled) throw;
        if (p.paid) throw;

        p.canceled = true;
        PaymentCanceled(_idPayment);
    }

    /// @notice `onlyOwner` Adds a spender to the `allowedSpenders[]` white list
    /// @param _spender The address of the contract being authorized/unauthorized
    /// @param _authorize `true` if authorizing and `false` if unauthorizing
    function authorizeSpender(address _spender, bool _authorize) onlyOwner {
        allowedSpenders[_spender] = _authorize;
        SpenderAuthorization(_spender, _authorize);
    }

    /// @notice `onlyOwner` Sets the address of `securityGuard`
    /// @param _newSecurityGuard Address of the new security guard
    function setSecurityGuard(address _newSecurityGuard) onlyOwner {
        securityGuard = _newSecurityGuard;
    }

    /// @notice `onlyOwner` Changes `timeLock`; the new `timeLock` cannot be
    ///  lower than `absoluteMinTimeLock`
    /// @param _newTimeLock Sets the new minimum default `timeLock` in seconds;
    ///  pending payments maintain their `earliestPayTime`
    function setTimelock(uint _newTimeLock) onlyOwner {
        if (_newTimeLock < absoluteMinTimeLock) throw;
        timeLock = _newTimeLock;
    }

    /// @notice `onlyOwner` Changes the maximum number of seconds
    /// `securityGuard` can delay a payment
    /// @param _maxSecurityGuardDelay The new maximum delay in seconds that
    ///  `securityGuard` can delay the payment's execution in total
    function setMaxSecurityGuardDelay(uint _maxSecurityGuardDelay) onlyOwner {
        maxSecurityGuardDelay = _maxSecurityGuardDelay;
    }
}


Add dedicated whitelister address

Add dedicated whitelister address

pragma solidity ^0.4.17;

import './token.sol';

/// @title Dutch auction contract - distribution of a fixed number of tokens using an auction.
/// The contract code is inspired by the Gnosis auction contract. Main difference is that the
/// auction ends if a fixed number of tokens was sold.
contract DutchAuction {
    /*
     * Auction for the RDN Token.
     *
     * Terminology:
     * 1 token unit = Rei
     * 1 token = RDN = Rei * token_multiplier
     * token_multiplier set from token's number of decimals (i.e. 10 ** decimals)
     */

    // Wait 7 days after the end of the auction, before ayone can claim tokens
    uint constant public token_claim_waiting_period = 7 days;

    // Bid value over which the address has to be whitelisted
    // At deployment moment, equivalent with $15,000
    uint constant public bid_threshold = 50 ether;

    /*
     * Storage
     */

    RaidenToken public token;
    address public owner_address;
    address public wallet_address;
    address public whitelister_address;

    // Price decay function parameters to be changed depending on the desired outcome

    // Starting price in WEI; e.g. 2 * 10 ** 18
    uint public price_start;

    // Divisor constant; e.g. 524880000
    uint public price_constant;

    // Divisor exponent; e.g. 3
    uint32 public price_exponent;

    // For calculating elapsed time for price
    uint public start_time;
    uint public end_time;
    uint public start_block;

    // Keep track of all ETH received in the bids
    uint public received_wei;

    // Keep track of cumulative ETH funds for which the tokens have been claimed
    uint public funds_claimed;

    uint public token_multiplier;

    // Total number of Rei (RDN * token_multiplier) that will be auctioned
    uint public num_tokens_auctioned;

    // Wei per RDN (Rei * token_multiplier)
    uint public final_price;

    // Bidder address => bid value
    mapping (address => uint) public bids;

    // Whitelist for addresses that want to bid more than bid_threshold
    mapping (address => bool) public whitelist;

    Stages public stage;

    /*
     * Enums
     */
    enum Stages {
        AuctionDeployed,
        AuctionSetUp,
        AuctionStarted,
        AuctionEnded,
        TokensDistributed
    }

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

    modifier isOwner() {
        require(msg.sender == owner_address);
        _;
    }

    modifier isWhitelister() {
        require(msg.sender == whitelister_address);
        _;
    }

    /*
     * Events
     */

    event Deployed(
        uint indexed _price_start,
        uint indexed _price_constant,
        uint32 indexed _price_exponent
    );
    event Setup();
    event AuctionStarted(uint indexed _start_time, uint indexed _block_number);
    event BidSubmission(
        address indexed _sender,
        uint _amount,
        uint _missing_funds
    );
    event ClaimedTokens(address indexed _recipient, uint _sent_amount);
    event AuctionEnded(uint _final_price);
    event TokensDistributed();

    /*
     * Public functions
     */

    /// @dev Contract constructor function sets the starting price, divisor constant and
    /// divisor exponent for calculating the Dutch Auction price.
    /// @param _wallet_address Wallet address to which all contributed ETH will be forwarded.
    /// @param _price_start High price in WEI at which the auction starts.
    /// @param _price_constant Auction price divisor constant.
    /// @param _price_exponent Auction price divisor exponent.
    function DutchAuction(
        address _wallet_address,
        address _whitelister_address,
        uint _price_start,
        uint _price_constant,
        uint32 _price_exponent)
        public
    {
        require(_wallet_address != 0x0);
        require(_whitelister_address != 0x0);
        wallet_address = _wallet_address;
        whitelister_address = _whitelister_address;

        owner_address = msg.sender;
        stage = Stages.AuctionDeployed;
        changeSettings(_price_start, _price_constant, _price_exponent);
        Deployed(_price_start, _price_constant, _price_exponent);
    }

    /// @dev Fallback function for the contract, which calls bid() if the auction has started.
    function () public payable atStage(Stages.AuctionStarted) {
        bid();
    }

    /// @notice Set `_token_address` as the token address to be used in the auction.
    /// @dev Setup function sets external contracts addresses.
    /// @param _token_address Token address.
    function setup(address _token_address) public isOwner atStage(Stages.AuctionDeployed) {
        require(_token_address != 0x0);
        token = RaidenToken(_token_address);

        // Get number of Rei (RDN * token_multiplier) to be auctioned from token auction balance
        num_tokens_auctioned = token.balanceOf(address(this));

        // Set the number of the token multiplier for its decimals
        token_multiplier = 10 ** uint(token.decimals());

        stage = Stages.AuctionSetUp;
        Setup();
    }

    /// @notice Set `_price_start`, `_price_constant` and `_price_exponent` as
    /// the new starting price, price divisor constant and price divisor exponent.
    /// @dev Changes auction price function parameters before auction is started.
    /// @param _price_start Updated start price.
    /// @param _price_constant Updated price divisor constant.
    /// @param _price_exponent Updated price divisor exponent.
    function changeSettings(
        uint _price_start,
        uint _price_constant,
        uint32 _price_exponent)
        internal
    {
        require(stage == Stages.AuctionDeployed || stage == Stages.AuctionSetUp);
        require(_price_start > 0);
        require(_price_constant > 0);

        price_start = _price_start;
        price_constant = _price_constant;
        price_exponent = _price_exponent;
    }

    /// @notice Adds account addresses to whitelist.
    /// @dev Adds account addresses to whitelist.
    /// @param _bidder_addresses Array of addresses.
    function addToWhitelist(address[] _bidder_addresses) public isWhitelister {
        for (uint32 i = 0; i < _bidder_addresses.length; i++) {
            whitelist[_bidder_addresses[i]] = true;
        }
    }

    /// @notice Removes account addresses from whitelist.
    /// @dev Removes account addresses from whitelist.
    /// @param _bidder_addresses Array of addresses.
    function removeFromWhitelist(address[] _bidder_addresses) public isWhitelister {
        for (uint32 i = 0; i < _bidder_addresses.length; i++) {
            whitelist[_bidder_addresses[i]] = false;
        }
    }

    /// @notice Start the auction.
    /// @dev Starts auction and sets start_time.
    function startAuction() public isOwner atStage(Stages.AuctionSetUp) {
        stage = Stages.AuctionStarted;
        start_time = now;
        start_block = block.number;
        AuctionStarted(start_time, start_block);
    }

    /// @notice Finalize the auction - sets the final RDN token price and changes the auction
    /// stage after no bids are allowed anymore.
    /// @dev Finalize auction and set the final RDN token price.
    function finalizeAuction() public atStage(Stages.AuctionStarted)
    {
        // Missing funds should be 0 at this point
        uint missing_funds = missingFundsToEndAuction();
        require(missing_funds == 0);

        // Calculate the final price = WEI / RDN = WEI / (Rei / token_multiplier)
        // Reminder: num_tokens_auctioned is the number of Rei (RDN * token_multiplier) that are auctioned
        final_price = token_multiplier * received_wei / num_tokens_auctioned;

        end_time = now;
        stage = Stages.AuctionEnded;
        AuctionEnded(final_price);

        assert(final_price > 0);
    }

    /// --------------------------------- Auction Functions ------------------

    /// @notice Send `msg.value` WEI to the auction from the `msg.sender` account.
    /// @dev Allows to send a bid to the auction.
    function bid()
        public
        payable
        atStage(Stages.AuctionStarted)
    {
        require(msg.value > 0);
        require(bids[msg.sender] + msg.value <= bid_threshold || whitelist[msg.sender]);
        assert(bids[msg.sender] + msg.value >= msg.value);

        // Missing funds without the current bid value
        uint missing_funds = missingFundsToEndAuction();

        // We require bid values to be less than the funds missing to end the auction
        // at the current price.
        require(msg.value <= missing_funds);

        bids[msg.sender] += msg.value;
        received_wei += msg.value;

        // Send bid amount to wallet
        wallet_address.transfer(msg.value);

        BidSubmission(msg.sender, msg.value, missing_funds);

        assert(received_wei >= msg.value);
    }

    /// @notice Claim auction tokens for `msg.sender` after the auction has ended.
    /// @dev Claims tokens for `msg.sender` after auction. To be used if tokens can
    /// be claimed by beneficiaries, individually.
    function claimTokens() public atStage(Stages.AuctionEnded) returns (bool) {
        return proxyClaimTokens(msg.sender);
    }

    /// @notice Claim auction tokens for `receiver_address` after the auction has ended.
    /// @dev Claims tokens for `receiver_address` after auction has ended.
    /// @param receiver_address Tokens will be assigned to this address if eligible.
    function proxyClaimTokens(address receiver_address)
        public
        atStage(Stages.AuctionEnded)
        returns (bool)
    {
        // Waiting period after the end of the auction, before anyone can claim tokens
        // Ensures enough time to check if auction was finalized correctly
        // before users start transacting tokens
        require(now > end_time + token_claim_waiting_period);
        require(receiver_address != 0x0);

        if (bids[receiver_address] == 0) {
            return false;
        }

        // Number of Rei = bid_wei / Rei = bid_wei / (wei_per_RDN * token_multiplier)
        uint num = (token_multiplier * bids[receiver_address]) / final_price;

        // Due to final_price floor rounding, the number of assigned tokens may be higher
        // than expected. Therefore, the number of remaining unassigned auction tokens
        // may be smaller than the number of tokens needed for the last claimTokens call
        uint auction_tokens_balance = token.balanceOf(address(this));
        if (num > auction_tokens_balance) {
            num = auction_tokens_balance;
        }

        // Update the total amount of funds for which tokens have been claimed
        funds_claimed += bids[receiver_address];

        // Set receiver bid to 0 before assigning tokens
        bids[receiver_address] = 0;

        require(token.transfer(receiver_address, num));

        ClaimedTokens(receiver_address, num);

        // After the last tokens are claimed, we change the auction stage
        // Due to the above logic, rounding errors will not be an issue
        if (funds_claimed == received_wei) {
            stage = Stages.TokensDistributed;
            TokensDistributed();
        }

        assert(token.balanceOf(receiver_address) >= num);
        assert(bids[receiver_address] == 0);
        return true;
    }

    /// @notice Get the RDN price in WEI during the auction, at the time of
    /// calling this function. Returns `0` if auction has ended.
    /// Returns `price_start` before auction has started.
    /// @dev Calculates the current RDN token price in WEI.
    /// @return Returns WEI per RDN (token_multiplier * Rei).
    function price() public constant returns (uint) {
        if (stage == Stages.AuctionEnded ||
            stage == Stages.TokensDistributed) {
            return 0;
        }
        return calcTokenPrice();
    }

    /// @notice Get the missing funds needed to end the auction,
    /// calculated at the current RDN price in WEI.
    /// @dev The missing funds amount necessary to end the auction at the current RDN price in WEI.
    /// @return Returns the missing funds amount in WEI.
    function missingFundsToEndAuction() constant public returns (uint) {

        // num_tokens_auctioned = total number of Rei (RDN * token_multiplier) that is auctioned
        uint required_wei_at_price = num_tokens_auctioned * price() / token_multiplier;
        if (required_wei_at_price <= received_wei) {
            return 0;
        }

        // assert(required_wei_at_price - received_wei > 0);
        return required_wei_at_price - received_wei;
    }

    /*
     *  Private functions
     */

    /// @dev Calculates the token price (WEI / RDN) at the current timestamp
    /// during the auction; elapsed time = 0 before auction starts.
    /// Based on the provided parameters, the price does not change in the first
    /// `price_constant^(1/price_exponent)` seconds due to rounding.
    /// Rounding in `decay_rate` also produces values that increase instead of decrease
    /// in the beginning; these spikes decrease over time and are noticeable
    /// only in first hours. This should be calculated before usage.
    /// @return Returns the token price - Wei per RDN.
    function calcTokenPrice() constant private returns (uint) {
        uint elapsed;
        if (stage == Stages.AuctionStarted) {
            elapsed = now - start_time;
        }

        uint decay_rate = elapsed ** price_exponent / price_constant;
        return price_start * (1 + elapsed) / (1 + elapsed + decay_rate);
    }
}

pragma solidity ^0.4.17;

import './token.sol';

/// @title Dutch auction contract - distribution of a fixed number of tokens using an auction.
/// The contract code is inspired by the Gnosis auction contract. Main difference is that the
/// auction ends if a fixed number of tokens was sold.
contract DutchAuction {
    /*
     * Auction for the RDN Token.
     *
     * Terminology:
     * 1 token unit = Rei
     * 1 token = RDN = Rei * token_multiplier
     * token_multiplier set from token's number of decimals (i.e. 10 ** decimals)
     */

    // Wait 7 days after the end of the auction, before ayone can claim tokens
    uint constant public token_claim_waiting_period = 7 days;

    // Bid value over which the address has to be whitelisted
    // At deployment moment, equivalent with $15,000
    uint constant public bid_threshold = 50 ether;

    /*
     * Storage
     */

    RaidenToken public token;
    address public owner_address;
    address public wallet_address;

    // Price decay function parameters to be changed depending on the desired outcome

    // Starting price in WEI; e.g. 2 * 10 ** 18
    uint public price_start;

    // Divisor constant; e.g. 524880000
    uint public price_constant;

    // Divisor exponent; e.g. 3
    uint32 public price_exponent;

    // For calculating elapsed time for price
    uint public start_time;
    uint public end_time;
    uint public start_block;

    // Keep track of all ETH received in the bids
    uint public received_wei;

    // Keep track of cumulative ETH funds for which the tokens have been claimed
    uint public funds_claimed;

    uint public token_multiplier;

    // Total number of Rei (RDN * token_multiplier) that will be auctioned
    uint public num_tokens_auctioned;

    // Wei per RDN (Rei * token_multiplier)
    uint public final_price;

    // Bidder address => bid value
    mapping (address => uint) public bids;

    // Whitelist for addresses that want to bid more than bid_threshold
    mapping (address => bool) public whitelist;

    Stages public stage;

    /*
     * Enums
     */
    enum Stages {
        AuctionDeployed,
        AuctionSetUp,
        AuctionStarted,
        AuctionEnded,
        TokensDistributed
    }

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

    modifier isOwner() {
        require(msg.sender == owner_address);
        _;
    }

    /*
     * Events
     */

    event Deployed(
        uint indexed _price_start,
        uint indexed _price_constant,
        uint32 indexed _price_exponent
    );
    event Setup();
    event AuctionStarted(uint indexed _start_time, uint indexed _block_number);
    event BidSubmission(
        address indexed _sender,
        uint _amount,
        uint _missing_funds
    );
    event ClaimedTokens(address indexed _recipient, uint _sent_amount);
    event AuctionEnded(uint _final_price);
    event TokensDistributed();

    /*
     * Public functions
     */

    /// @dev Contract constructor function sets the starting price, divisor constant and
    /// divisor exponent for calculating the Dutch Auction price.
    /// @param _wallet_address Wallet address to which all contributed ETH will be forwarded.
    /// @param _price_start High price in WEI at which the auction starts.
    /// @param _price_constant Auction price divisor constant.
    /// @param _price_exponent Auction price divisor exponent.
    function DutchAuction(
        address _wallet_address,
        uint _price_start,
        uint _price_constant,
        uint32 _price_exponent)
        public
    {
        require(_wallet_address != 0x0);
        wallet_address = _wallet_address;

        owner_address = msg.sender;
        stage = Stages.AuctionDeployed;
        changeSettings(_price_start, _price_constant, _price_exponent);
        Deployed(_price_start, _price_constant, _price_exponent);
    }

    /// @dev Fallback function for the contract, which calls bid() if the auction has started.
    function () public payable atStage(Stages.AuctionStarted) {
        bid();
    }

    /// @notice Set `_token_address` as the token address to be used in the auction.
    /// @dev Setup function sets external contracts addresses.
    /// @param _token_address Token address.
    function setup(address _token_address) public isOwner atStage(Stages.AuctionDeployed) {
        require(_token_address != 0x0);
        token = RaidenToken(_token_address);

        // Get number of Rei (RDN * token_multiplier) to be auctioned from token auction balance
        num_tokens_auctioned = token.balanceOf(address(this));

        // Set the number of the token multiplier for its decimals
        token_multiplier = 10 ** uint(token.decimals());

        stage = Stages.AuctionSetUp;
        Setup();
    }

    /// @notice Set `_price_start`, `_price_constant` and `_price_exponent` as
    /// the new starting price, price divisor constant and price divisor exponent.
    /// @dev Changes auction price function parameters before auction is started.
    /// @param _price_start Updated start price.
    /// @param _price_constant Updated price divisor constant.
    /// @param _price_exponent Updated price divisor exponent.
    function changeSettings(
        uint _price_start,
        uint _price_constant,
        uint32 _price_exponent)
        internal
    {
        require(stage == Stages.AuctionDeployed || stage == Stages.AuctionSetUp);
        require(_price_start > 0);
        require(_price_constant > 0);

        price_start = _price_start;
        price_constant = _price_constant;
        price_exponent = _price_exponent;
    }

    /// @notice Adds account addresses to whitelist.
    /// @dev Adds account addresses to whitelist.
    /// @param _bidder_addresses Array of addresses.
    function addToWhitelist(address[] _bidder_addresses) public isOwner {
        for (uint32 i = 0; i < _bidder_addresses.length; i++) {
            whitelist[_bidder_addresses[i]] = true;
        }
    }

    /// @notice Removes account addresses from whitelist.
    /// @dev Removes account addresses from whitelist.
    /// @param _bidder_addresses Array of addresses.
    function removeFromWhitelist(address[] _bidder_addresses) public isOwner {
        for (uint32 i = 0; i < _bidder_addresses.length; i++) {
            whitelist[_bidder_addresses[i]] = false;
        }
    }

    /// @notice Start the auction.
    /// @dev Starts auction and sets start_time.
    function startAuction() public isOwner atStage(Stages.AuctionSetUp) {
        stage = Stages.AuctionStarted;
        start_time = now;
        start_block = block.number;
        AuctionStarted(start_time, start_block);
    }

    /// @notice Finalize the auction - sets the final RDN token price and changes the auction
    /// stage after no bids are allowed anymore.
    /// @dev Finalize auction and set the final RDN token price.
    function finalizeAuction() public atStage(Stages.AuctionStarted)
    {
        // Missing funds should be 0 at this point
        uint missing_funds = missingFundsToEndAuction();
        require(missing_funds == 0);

        // Calculate the final price = WEI / RDN = WEI / (Rei / token_multiplier)
        // Reminder: num_tokens_auctioned is the number of Rei (RDN * token_multiplier) that are auctioned
        final_price = token_multiplier * received_wei / num_tokens_auctioned;

        end_time = now;
        stage = Stages.AuctionEnded;
        AuctionEnded(final_price);

        assert(final_price > 0);
    }

    /// --------------------------------- Auction Functions ------------------

    /// @notice Send `msg.value` WEI to the auction from the `msg.sender` account.
    /// @dev Allows to send a bid to the auction.
    function bid()
        public
        payable
        atStage(Stages.AuctionStarted)
    {
        require(msg.value > 0);
        require(bids[msg.sender] + msg.value <= bid_threshold || whitelist[msg.sender]);
        assert(bids[msg.sender] + msg.value >= msg.value);

        // Missing funds without the current bid value
        uint missing_funds = missingFundsToEndAuction();

        // We require bid values to be less than the funds missing to end the auction
        // at the current price.
        require(msg.value <= missing_funds);

        bids[msg.sender] += msg.value;
        received_wei += msg.value;

        // Send bid amount to wallet
        wallet_address.transfer(msg.value);

        BidSubmission(msg.sender, msg.value, missing_funds);

        assert(received_wei >= msg.value);
    }

    /// @notice Claim auction tokens for `msg.sender` after the auction has ended.
    /// @dev Claims tokens for `msg.sender` after auction. To be used if tokens can
    /// be claimed by beneficiaries, individually.
    function claimTokens() public atStage(Stages.AuctionEnded) returns (bool) {
        return proxyClaimTokens(msg.sender);
    }

    /// @notice Claim auction tokens for `receiver_address` after the auction has ended.
    /// @dev Claims tokens for `receiver_address` after auction has ended.
    /// @param receiver_address Tokens will be assigned to this address if eligible.
    function proxyClaimTokens(address receiver_address)
        public
        atStage(Stages.AuctionEnded)
        returns (bool)
    {
        // Waiting period after the end of the auction, before anyone can claim tokens
        // Ensures enough time to check if auction was finalized correctly
        // before users start transacting tokens
        require(now > end_time + token_claim_waiting_period);
        require(receiver_address != 0x0);

        if (bids[receiver_address] == 0) {
            return false;
        }

        // Number of Rei = bid_wei / Rei = bid_wei / (wei_per_RDN * token_multiplier)
        uint num = (token_multiplier * bids[receiver_address]) / final_price;

        // Due to final_price floor rounding, the number of assigned tokens may be higher
        // than expected. Therefore, the number of remaining unassigned auction tokens
        // may be smaller than the number of tokens needed for the last claimTokens call
        uint auction_tokens_balance = token.balanceOf(address(this));
        if (num > auction_tokens_balance) {
            num = auction_tokens_balance;
        }

        // Update the total amount of funds for which tokens have been claimed
        funds_claimed += bids[receiver_address];

        // Set receiver bid to 0 before assigning tokens
        bids[receiver_address] = 0;

        require(token.transfer(receiver_address, num));

        ClaimedTokens(receiver_address, num);

        // After the last tokens are claimed, we change the auction stage
        // Due to the above logic, rounding errors will not be an issue
        if (funds_claimed == received_wei) {
            stage = Stages.TokensDistributed;
            TokensDistributed();
        }

        assert(token.balanceOf(receiver_address) >= num);
        assert(bids[receiver_address] == 0);
        return true;
    }

    /// @notice Get the RDN price in WEI during the auction, at the time of
    /// calling this function. Returns `0` if auction has ended.
    /// Returns `price_start` before auction has started.
    /// @dev Calculates the current RDN token price in WEI.
    /// @return Returns WEI per RDN (token_multiplier * Rei).
    function price() public constant returns (uint) {
        if (stage == Stages.AuctionEnded ||
            stage == Stages.TokensDistributed) {
            return 0;
        }
        return calcTokenPrice();
    }

    /// @notice Get the missing funds needed to end the auction,
    /// calculated at the current RDN price in WEI.
    /// @dev The missing funds amount necessary to end the auction at the current RDN price in WEI.
    /// @return Returns the missing funds amount in WEI.
    function missingFundsToEndAuction() constant public returns (uint) {

        // num_tokens_auctioned = total number of Rei (RDN * token_multiplier) that is auctioned
        uint required_wei_at_price = num_tokens_auctioned * price() / token_multiplier;
        if (required_wei_at_price <= received_wei) {
            return 0;
        }

        // assert(required_wei_at_price - received_wei > 0);
        return required_wei_at_price - received_wei;
    }

    /*
     *  Private functions
     */

    /// @dev Calculates the token price (WEI / RDN) at the current timestamp
    /// during the auction; elapsed time = 0 before auction starts.
    /// Based on the provided parameters, the price does not change in the first
    /// `price_constant^(1/price_exponent)` seconds due to rounding.
    /// Rounding in `decay_rate` also produces values that increase instead of decrease
    /// in the beginning; these spikes decrease over time and are noticeable
    /// only in first hours. This should be calculated before usage.
    /// @return Returns the token price - Wei per RDN.
    function calcTokenPrice() constant private returns (uint) {
        uint elapsed;
        if (stage == Stages.AuctionStarted) {
            elapsed = now - start_time;
        }

        uint decay_rate = elapsed ** price_exponent / price_constant;
        return price_start * (1 + elapsed) / (1 + elapsed + decay_rate);
    }
}