Use SafeMath in Minter for consistency

Use SafeMath in Minter for consistency

pragma solidity ^0.4.17;

import "../Manager.sol";
import "./IMinter.sol";
import "./ILivepeerToken.sol";
import "../rounds/IRoundsManager.sol";
import "../bonding/IBondingManager.sol";
import "../libraries/MathUtils.sol";

import "zeppelin-solidity/contracts/math/SafeMath.sol";

/**
 * @title Minter
 * @dev Manages inflation rate and the minting of new tokens for each round of the Livepeer protocol
 */
contract Minter is Manager, IMinter {
    using SafeMath for uint256;

    // Per round inflation rate
    uint256 public inflation;
    // Change in inflation rate per round until the target bonding rate is achieved
    uint256 public inflationChange;
    // Target bonding rate
    uint256 public targetBondingRate;

    // Current number of mintable tokens. Reset every round
    uint256 public currentMintableTokens;
    // Current number of minted tokens. Reset every round
    uint256 public currentMintedTokens;

    // Checks if caller is BondingManager
    modifier onlyBondingManager() {
        require(msg.sender == controller.getContract(keccak256("BondingManager")));
        _;
    }

    // Checks if caller is RoundsManager
    modifier onlyRoundsManager() {
        require(msg.sender == controller.getContract(keccak256("RoundsManager")));
        _;
    }

    // Checks if caller is either BondingManager or JobsManager
    modifier onlyBondingManagerOrJobsManager() {
        require(msg.sender == controller.getContract(keccak256("BondingManager")) || msg.sender == controller.getContract(keccak256("JobsManager")));
        _;
    }

    // Checks if caller is either the currently registered Minter or JobsManager
    modifier onlyMinterOrJobsManager() {
        require(msg.sender == controller.getContract(keccak256("Minter")) || msg.sender == controller.getContract(keccak256("JobsManager")));
        _;
    }

    /**
     * @dev Minter constructor
     * @param _inflation Base inflation rate as a percentage of current total token supply
     * @param _inflationChange Change in inflation rate each round (increase or decrease) if target bonding rate is not achieved
     * @param _targetBondingRate Target bonding rate as a percentage of total bonded tokens / total token supply
     */
    function Minter(address _controller, uint256 _inflation, uint256 _inflationChange, uint256 _targetBondingRate) public Manager(_controller) {
        // Inflation must be valid percentage
        require(MathUtils.validPerc(_inflation));
        // Inflation change must be valid percentage
        require(MathUtils.validPerc(_inflationChange));
        // Target bonding rate must be valid percentage
        require(MathUtils.validPerc(_targetBondingRate));

        inflation = _inflation;
        inflationChange = _inflationChange;
        targetBondingRate = _targetBondingRate;
    }

    /**
     * @dev Set targetBondingRate. Only callable by Controller owner
     * @param _targetBondingRate Target bonding rate as a percentage of total bonded tokens / total token supply
     */
    function setTargetBondingRate(uint256 _targetBondingRate) external onlyControllerOwner {
        // Must be valid percentage
        require(MathUtils.validPerc(_targetBondingRate));

        targetBondingRate = _targetBondingRate;

        ParameterUpdate("targetBondingRate");
    }

    /**
     * @dev Set inflationChange. Only callable by Controller owner
     * @param _inflationChange Inflation change as a percentage of total token supply
     */
    function setInflationChange(uint256 _inflationChange) external onlyControllerOwner {
        // Must be valid percentage
        require(MathUtils.validPerc(_inflationChange));

        inflationChange = _inflationChange;

        ParameterUpdate("inflationChange");
    }

    /**
     * @dev Migrate to a new Minter by transferring ownership of the token as well
     * as the current Minter's token balance to the new Minter. Only callable by Controller when system is paused
     * @param _newMinter Address of new Minter
     */
    function migrateToNewMinter(IMinter _newMinter) external onlyControllerOwner whenSystemPaused {
        // New Minter cannot be the current Minter
        require(_newMinter != this);
        // Check for null address
        require(address(_newMinter) != address(0));

        IController newMinterController = _newMinter.getController();
        // New Minter must have same Controller as current Minter
        require(newMinterController == controller);
        // New Minter's Controller must have the current Minter registered
        require(newMinterController.getContract(keccak256("Minter")) == address(this));

        // Transfer ownership of token to new Minter
        livepeerToken().transferOwnership(_newMinter);
        // Transfer current Minter's token balance to new Minter
        livepeerToken().transfer(_newMinter, livepeerToken().balanceOf(this));
        // Transfer current Minter's ETH balance to new Minter
        _newMinter.depositETH.value(this.balance)();
    }

    /**
     * @dev Create reward based on a fractional portion of the mintable tokens for the current round
     * @param _fracNum Numerator of fraction (active transcoder's stake)
     * @param _fracDenom Denominator of fraction (total active stake)
     */
    function createReward(uint256 _fracNum, uint256 _fracDenom) external onlyBondingManager whenSystemNotPaused returns (uint256) {
        // Compute and mint fraction of mintable tokens to include in reward
        uint256 mintAmount = MathUtils.percOf(currentMintableTokens, _fracNum, _fracDenom);
        // Update amount of minted tokens for round
        currentMintedTokens = currentMintedTokens.add(mintAmount);
        // Minted tokens must not exceed mintable tokens
        require(currentMintedTokens <= currentMintableTokens);
        // Mint new tokens
        livepeerToken().mint(this, mintAmount);

        // Reward = minted tokens
        return mintAmount;
    }

    /**
     * @dev Transfer tokens to a receipient. Only callable by BondingManager - always trusts BondingManager
     * @param _to Recipient address
     * @param _amount Amount of tokens
     */
    function trustedTransferTokens(address _to, uint256 _amount) external onlyBondingManager whenSystemNotPaused {
        livepeerToken().transfer(_to, _amount);
    }

    /**
     * @dev Burn tokens. Only callable by BondingManager - always trusts BondingManager
     * @param _amount Amount of tokens to burn
     */
    function trustedBurnTokens(uint256 _amount) external onlyBondingManager whenSystemNotPaused {
        livepeerToken().burn(_amount);
    }

    /**
     * @dev Withdraw ETH to a recipient. Only callable by BondingManager or JobsManager - always trusts these two contracts
     * @param _to Recipient address
     * @param _amount Amount of ETH
     */
    function trustedWithdrawETH(address _to, uint256 _amount) external onlyBondingManagerOrJobsManager whenSystemNotPaused {
        _to.transfer(_amount);
    }

    /**
     * @dev Deposit ETH to this contract. Only callable by the currently registered Minter or JobsManager
     */
    function depositETH() external payable onlyMinterOrJobsManager whenSystemNotPaused returns (bool) {
        return true;
    }

    /**
     * @dev Set inflation and mintable tokens for the round. Only callable by the RoundsManager
     */
    function setCurrentRewardTokens() external onlyRoundsManager whenSystemNotPaused {
        setInflation();

        // Set mintable tokens based upon current inflation and current total token supply
        currentMintableTokens = MathUtils.percOf(livepeerToken().totalSupply(), inflation);
        currentMintedTokens = 0;

        SetCurrentRewardTokens(currentMintableTokens, inflation);
    }

    /**
     * @dev Returns Controller interface
     */
    function getController() public view returns (IController) {
        return controller;
    }

    /**
     * @dev Set inflation based upon the current bonding rate and target bonding rate
     */
    function setInflation() internal {
        uint256 currentBondingRate = 0;
        uint256 totalSupply = livepeerToken().totalSupply();

        if (totalSupply > 0) {
            uint256 totalBonded = bondingManager().getTotalBonded();
            currentBondingRate = MathUtils.percPoints(totalBonded, totalSupply);
        }

        if (currentBondingRate < targetBondingRate) {
            // Bonding rate is below the target - increase inflation
            inflation = inflation.add(inflationChange);
        } else if (currentBondingRate > targetBondingRate) {
            // Bonding rate is above the target - decrease inflation
            if (inflationChange > inflation) {
                inflation = 0;
            } else {
                inflation = inflation.sub(inflationChange);
            }
        }
    }

    /**
     * @dev Returns LivepeerToken interface
     */
    function livepeerToken() internal view returns (ILivepeerToken) {
        return ILivepeerToken(controller.getContract(keccak256("LivepeerToken")));
    }

    /**
     * @dev Returns BondingManager interface
     */
    function bondingManager() internal view returns (IBondingManager) {
        return IBondingManager(controller.getContract(keccak256("BondingManager")));
    }
}

pragma solidity ^0.4.17;

import "../Manager.sol";
import "./IMinter.sol";
import "./ILivepeerToken.sol";
import "../rounds/IRoundsManager.sol";
import "../bonding/IBondingManager.sol";
import "../libraries/MathUtils.sol";

import "zeppelin-solidity/contracts/math/SafeMath.sol";

/**
 * @title Minter
 * @dev Manages inflation rate and the minting of new tokens for each round of the Livepeer protocol
 */
contract Minter is Manager, IMinter {
    using SafeMath for uint256;

    // Per round inflation rate
    uint256 public inflation;
    // Change in inflation rate per round until the target bonding rate is achieved
    uint256 public inflationChange;
    // Target bonding rate
    uint256 public targetBondingRate;

    // Current number of mintable tokens. Reset every round
    uint256 public currentMintableTokens;
    // Current number of minted tokens. Reset every round
    uint256 public currentMintedTokens;

    // Checks if caller is BondingManager
    modifier onlyBondingManager() {
        require(msg.sender == controller.getContract(keccak256("BondingManager")));
        _;
    }

    // Checks if caller is RoundsManager
    modifier onlyRoundsManager() {
        require(msg.sender == controller.getContract(keccak256("RoundsManager")));
        _;
    }

    // Checks if caller is either BondingManager or JobsManager
    modifier onlyBondingManagerOrJobsManager() {
        require(msg.sender == controller.getContract(keccak256("BondingManager")) || msg.sender == controller.getContract(keccak256("JobsManager")));
        _;
    }

    // Checks if caller is either the currently registered Minter or JobsManager
    modifier onlyMinterOrJobsManager() {
        require(msg.sender == controller.getContract(keccak256("Minter")) || msg.sender == controller.getContract(keccak256("JobsManager")));
        _;
    }

    /**
     * @dev Minter constructor
     * @param _inflation Base inflation rate as a percentage of current total token supply
     * @param _inflationChange Change in inflation rate each round (increase or decrease) if target bonding rate is not achieved
     * @param _targetBondingRate Target bonding rate as a percentage of total bonded tokens / total token supply
     */
    function Minter(address _controller, uint256 _inflation, uint256 _inflationChange, uint256 _targetBondingRate) public Manager(_controller) {
        // Inflation must be valid percentage
        require(MathUtils.validPerc(_inflation));
        // Inflation change must be valid percentage
        require(MathUtils.validPerc(_inflationChange));
        // Target bonding rate must be valid percentage
        require(MathUtils.validPerc(_targetBondingRate));

        inflation = _inflation;
        inflationChange = _inflationChange;
        targetBondingRate = _targetBondingRate;
    }

    /**
     * @dev Set targetBondingRate. Only callable by Controller owner
     * @param _targetBondingRate Target bonding rate as a percentage of total bonded tokens / total token supply
     */
    function setTargetBondingRate(uint256 _targetBondingRate) external onlyControllerOwner {
        // Must be valid percentage
        require(MathUtils.validPerc(_targetBondingRate));

        targetBondingRate = _targetBondingRate;

        ParameterUpdate("targetBondingRate");
    }

    /**
     * @dev Set inflationChange. Only callable by Controller owner
     * @param _inflationChange Inflation change as a percentage of total token supply
     */
    function setInflationChange(uint256 _inflationChange) external onlyControllerOwner {
        // Must be valid percentage
        require(MathUtils.validPerc(_inflationChange));

        inflationChange = _inflationChange;

        ParameterUpdate("inflationChange");
    }

    /**
     * @dev Migrate to a new Minter by transferring ownership of the token as well
     * as the current Minter's token balance to the new Minter. Only callable by Controller when system is paused
     * @param _newMinter Address of new Minter
     */
    function migrateToNewMinter(IMinter _newMinter) external onlyControllerOwner whenSystemPaused {
        // New Minter cannot be the current Minter
        require(_newMinter != this);
        // Check for null address
        require(address(_newMinter) != address(0));

        IController newMinterController = _newMinter.getController();
        // New Minter must have same Controller as current Minter
        require(newMinterController == controller);
        // New Minter's Controller must have the current Minter registered
        require(newMinterController.getContract(keccak256("Minter")) == address(this));

        // Transfer ownership of token to new Minter
        livepeerToken().transferOwnership(_newMinter);
        // Transfer current Minter's token balance to new Minter
        livepeerToken().transfer(_newMinter, livepeerToken().balanceOf(this));
        // Transfer current Minter's ETH balance to new Minter
        _newMinter.depositETH.value(this.balance)();
    }

    /**
     * @dev Create reward based on a fractional portion of the mintable tokens for the current round
     * @param _fracNum Numerator of fraction (active transcoder's stake)
     * @param _fracDenom Denominator of fraction (total active stake)
     */
    function createReward(uint256 _fracNum, uint256 _fracDenom) external onlyBondingManager whenSystemNotPaused returns (uint256) {
        // Compute and mint fraction of mintable tokens to include in reward
        uint256 mintAmount = MathUtils.percOf(currentMintableTokens, _fracNum, _fracDenom);
        // Update amount of minted tokens for round
        currentMintedTokens = currentMintedTokens.add(mintAmount);
        // Minted tokens must not exceed mintable tokens
        require(currentMintedTokens <= currentMintableTokens);
        // Mint new tokens
        livepeerToken().mint(this, mintAmount);

        // Reward = minted tokens
        return mintAmount;
    }

    /**
     * @dev Transfer tokens to a receipient. Only callable by BondingManager - always trusts BondingManager
     * @param _to Recipient address
     * @param _amount Amount of tokens
     */
    function trustedTransferTokens(address _to, uint256 _amount) external onlyBondingManager whenSystemNotPaused {
        livepeerToken().transfer(_to, _amount);
    }

    /**
     * @dev Burn tokens. Only callable by BondingManager - always trusts BondingManager
     * @param _amount Amount of tokens to burn
     */
    function trustedBurnTokens(uint256 _amount) external onlyBondingManager whenSystemNotPaused {
        livepeerToken().burn(_amount);
    }

    /**
     * @dev Withdraw ETH to a recipient. Only callable by BondingManager or JobsManager - always trusts these two contracts
     * @param _to Recipient address
     * @param _amount Amount of ETH
     */
    function trustedWithdrawETH(address _to, uint256 _amount) external onlyBondingManagerOrJobsManager whenSystemNotPaused {
        _to.transfer(_amount);
    }

    /**
     * @dev Deposit ETH to this contract. Only callable by the currently registered Minter or JobsManager
     */
    function depositETH() external payable onlyMinterOrJobsManager whenSystemNotPaused returns (bool) {
        return true;
    }

    /**
     * @dev Set inflation and mintable tokens for the round. Only callable by the RoundsManager
     */
    function setCurrentRewardTokens() external onlyRoundsManager whenSystemNotPaused {
        setInflation();

        // Set mintable tokens based upon current inflation and current total token supply
        currentMintableTokens = MathUtils.percOf(livepeerToken().totalSupply(), inflation);
        currentMintedTokens = 0;

        SetCurrentRewardTokens(currentMintableTokens, inflation);
    }

    /**
     * @dev Returns Controller interface
     */
    function getController() public view returns (IController) {
        return controller;
    }

    /**
     * @dev Set inflation based upon the current bonding rate and target bonding rate
     */
    function setInflation() internal {
        uint256 currentBondingRate = 0;
        uint256 totalSupply = livepeerToken().totalSupply();

        if (totalSupply > 0) {
            uint256 totalBonded = bondingManager().getTotalBonded();
            currentBondingRate = MathUtils.percPoints(totalBonded, totalSupply);
        }

        if (currentBondingRate < targetBondingRate) {
            // Bonding rate is below the target - increase inflation
            inflation = inflation.add(inflationChange);
        } else if (currentBondingRate > targetBondingRate) {
            // Bonding rate is above the target - decrease inflation
            if (inflationChange > inflation) {
                inflation = 0;
            } else {
                inflation -= inflationChange;
            }
        }
    }

    /**
     * @dev Returns LivepeerToken interface
     */
    function livepeerToken() internal view returns (ILivepeerToken) {
        return ILivepeerToken(controller.getContract(keccak256("LivepeerToken")));
    }

    /**
     * @dev Returns BondingManager interface
     */
    function bondingManager() internal view returns (IBondingManager) {
        return IBondingManager(controller.getContract(keccak256("BondingManager")));
    }
}


Delete ECDSASignatureProxy.sol

Delete ECDSASignatureProxy.sol

import "UnanimousConsent.sol";

/**
* This contract will call consent from the UnanimousConsent
* contract if and only if the signer has signed all of the hashes
**/
contract ECDSASignatureProxy {
    address signer;
    UnanimousConsent unanimousConsent;

    function ECDSASignatureProxy(address _signer, UnanimousConsent _unanimousConsent) {
        signer = _signer;
        unanimousConsent = _unanimousConsent;
    }

    function forward(bytes32[] hashes, uint8[] v, bytes32[] r, bytes32[] s) returns(bool) {
        uint length = hashes.length;
        for (uint i = length - 1; i <= 0; --i) {
            if (ecrecover(hashes[i], v[i], r[i], s[i]) != signer) {
                return false;
            }
        }
        return unanimousConsent.call(bytes4(sha3("consent(bytes32)")), hashes);
    }
}


SmartExchange.sol

SmartExchange.sol

import "owned";

contract SmartExchange is owned {
	event OnAnonymousDeposit(address indexed from, uint value);
	event OnDeposit(address indexed from, bytes indexed to, uint value);
	event OnTransfer(bytes indexed from, address indexed to, uint value);
	event OnIcapTransfer(bytes indexed from, address indexed to, bytes indirectId, uint value);

	function () {
		OnAnonymousDeposit(msg.sender, msg.value);
	}

	function deposit(bytes32 to) {
		OnDeposit(msg.sender, to, msg.value);
	}

	function transfer(bytes32 from, address to, uint value) onlyowner {
		to.send(value);
		onTransfer(from, to, value);
	}

	function icapTransfer(bytes32 from, address to, bytes32 indirectId, uint value) onlyowner {
		SmartExchange(to).deposit.value(value)(indirectId); // value?
		OnIcapTransfer(from, to, indirectId, value);
	}
}

error: pathspec 'lib/contracts/SmartExchange.sol' did not match any file(s) known to git


bugfixes

bugfixes

pragma solidity ^0.4.11;

/// @title Name Resolver for multiple contracts
/// Resolves contract names to their current version's address
contract NameResolver {
    address owner;
    mapping (bytes32 => address) backends;

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

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

    function getBackend(string contractName) returns (address) {
        return backends[keccak256(contractName)];
    }

    function changeBackend(string contractName, address newBackend) public onlyOwner() returns (bool) {
        bytes32 key = keccak256(contractName);
        if(newBackend != backends[key]) {
            backends[key] = newBackend;
            return true;
        }
        return false;
    }
}

pragma solidity ^0.4.11;

/// @title Name Resolver for multiple contracts
/// Resolves contract names to their current version's address
contract NameResolver {
    address owner;
    // Mapping is public and can be retrieved by any frontend
    mapping (string => address) public backends;
    // TODO: Consider adding history of previous backends

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

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

    function changeBackend(string contractName, address newBackend) public
    onlyOwner()
    returns (bool) {
        if(newBackend != backends[contractName]) {
            backends[contractName] = newBackend;
            return true;
        }

        return false;
    }
}


Add StateChannel code

Add StateChannel code

contract StateChannel {

	uint nonce = 0;
	mapping (bytes32 =>
			mapping (address => bool)) consents;
	address[] participants;

	modifier onlySelf {
		if (msg.sender == address(this)) {
			_
		} else {
			throw;
		}
	}

	function StateChannel(address[] _participants) {
		participants = _participants;
	}

	function eval(
		uint _nonce,
		address[] _calledContracts,
		bytes4[] _methodSignatures,
		uint[] _argumentLengths,
		bytes32[] _arguments
	) {
		if (
			_nonce <= nonce ||
			_calledContracts.length != _methodSignatures.length ||
			_calledContracts.length != _argumentLengths.length
		) {
			throw;
		}

		uint i;
		uint j;
		bytes32 hash = sha3(_nonce, _calledContracts, _methodSignatures, _argumentLengths, _arguments);

		for (i = 0; i < participants.length; i++) {
			if (!consents[hash][participants[i]]) {
				throw;
			}
		}
		nonce = _nonce;

		uint argumentsIndex = 0;
		for (i = 0; i < _calledContracts.length; i++) {

			bytes32[] memory arguments = new bytes32[](_argumentLengths[i]);
			for (j = 0; j < _argumentLengths[i]; j++) {
				arguments[j] = _arguments[argumentsIndex++];
			}

			if (!_calledContracts[i].call(_methodSignatures[i], arguments[i])) {
				throw;
			}
		}
	}

	function consent(bytes32 _hash) {
		consents[_hash][msg.sender] = true;
	}

	function sendEther(address _recipient, uint _amount) external onlySelf {
		if (!_recipient.send(_amount)) {
			throw;
		}
	}

	function changeParticipants(address[] _participants) external onlySelf {
		participants = _participants;
	}

	function clean(bytes32[] _hashes, address[] _participants) external onlySelf {
		for (uint i = 0; i < _hashes.length; i++) {
			for (uint j = 0; j < _participants.length; j++) {
				delete consents[_hashes[i]][_participants[j]];
			}
		}
	}

	function kill(address _recipient) external onlySelf {
		selfdestruct(_recipient);
	}
}


Fix primitive parsing to update count

Fix primitive parsing to update count

pragma solidity ^0.4.2;

contract JsmnSol {

    event Info(string msg);
    event TokenInfo(JsmnType jsmnType, int start, int end, uint8 size);
    event Debug(int toksuper, int length);

    enum JsmnType { UNDEFINED, OBJECT, ARRAY, STRING, PRIMITIVE }
    enum JsmnError { INVALID, ERROR_PART, NO_MEMORY}

    struct JsmnToken {
        JsmnType jsmnType;
        int start;
        int end;
        uint8 size;
    }

    struct Parser {
        uint pos;
        uint toknext;
        int toksuper;
    }

    JsmnToken[] storageTokens;

    function jsmnInit(uint length) internal returns (Parser, JsmnToken[]) {
        Parser memory p = Parser(0, 0, -1);
        JsmnToken[] memory t = new JsmnToken[](length);
        return (p, t);
    }

    function allocateToken(Parser parser, JsmnToken[] tokens) internal returns (bool, JsmnToken) {
        Info('allocateToken');
        if (parser.toknext >= tokens.length) {
            // no more space in tokens
            return (false, tokens[tokens.length-1]);
        }
        tokens[parser.toknext] = JsmnToken(JsmnType.UNDEFINED, -1, -1, 0);
        parser.toknext++;
        return (true, tokens[parser.toknext-1]);
    }

    function fillToken(JsmnToken token, JsmnType jsmnType, int start, int end) internal {
        token.jsmnType = jsmnType;
        token.start = start;
        token.end = end;
        token.size = 0;
    }

    function parseString(Parser parser, JsmnToken[] tokens, bytes s) internal returns (int) {
        uint start = parser.pos;
        parser.pos++;

        for (; parser.pos<s.length; parser.pos++) {
            bytes1 c = s[parser.pos];

            // Quote -> end of string
            if (c == '"') {
                var (success, token) = allocateToken(parser, tokens);
                if (!success) {
                    parser.pos = start;
                    return int(JsmnError.NO_MEMORY);
                }
                fillToken(token, JsmnType.STRING, int(start+1), int(parser.pos));
                return 0;
            }

            if (c == '\\') {
                // TODO handle escaped characters
            }
        }
        parser.pos = start;
        return int(JsmnError.ERROR_PART);
    }

    function parsePrimitive(Parser parser, JsmnToken[] tokens, bytes s) internal returns (int) {
        bool found = false;
        uint start = parser.pos;
        byte c;
        uint ti;
        for (; parser.pos < s.length; parser.pos++) {
            c = s[parser.pos];
            if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == ','
                || c == 0x7d || c == 0x5d) {
                    found = true;
                    break;
            }
            if (c < 32 || c > 127) {
                parser.pos = start;
                return int(JsmnError.INVALID);
            }
        }
        if (!found) {
            parser.pos = start;
            return int(JsmnError.ERROR_PART);
        }

        // found the end
        var (success, token) = allocateToken(parser, tokens);
        if (!success) {
            parser.pos = start;
            return int(JsmnError.NO_MEMORY);
        }
        fillToken(token, JsmnType.PRIMITIVE, int(start), int(parser.pos));
        parser.pos--;
        return 0;
    }

    function jsmnParse(string json, uint numberElements) returns (JsmnError) {
        bytes memory s = bytes(json);
        var (parser, tokens) = jsmnInit(numberElements);

        // JsmnToken memory token;
        int r;
        uint count = parser.toknext;
        uint i;

        for (; parser.pos<s.length; parser.pos++) {
            bytes1 c = s[parser.pos];

            // 0x7b, 0x5b opening parentheses
            if (c == 0x7b || c == 0x5b) {
                Info('Opening parentheses');
                count++;
                //token = allocateToken();
                var (success, token)= allocateToken(parser, tokens);
                if (!success) {
                    return JsmnError.NO_MEMORY;
                }
                if (parser.toksuper != -1) {
                    tokens[uint(parser.toksuper)].size++;
                }
                token.jsmnType = (c == 0x7b ? JsmnType.OBJECT : JsmnType.ARRAY);
                token.start = int(parser.pos);
                parser.toksuper = int(parser.toknext - 1);
                continue;
            }

            // closing parentheses
            if (c == 0x7d || c == 0x5d) {
                Info('Closing parentheses');
                JsmnType tokenType = (c == 0x7d ? JsmnType.OBJECT : JsmnType.ARRAY);
                bool isUpdated = false;
                for (i=parser.toknext -1; i>=0; i--) {
                    //token = tokens[uint(i)];
                    token = tokens[i];
                    if (token.start != -1 && token.end == -1) {
                        if (token.jsmnType != tokenType) {
                            // found a token that hasn't been closed but from a different type
                            Info('Error: wrong type');
                            return JsmnError.INVALID;
                        }
                        parser.toksuper = -1;
                        tokens[i].end = int(parser.pos + 1);
                        isUpdated = true;
                        break;
                    }
                }
                if (!isUpdated) {
                    Info('Error: No update');
                    return JsmnError.INVALID;
                }
                for (; i>0; i--) {
                    token = tokens[uint(i)];
                    if (token.start != -1 && token.end == -1) {
                        parser.toksuper = int(i);
                        break;
                    }
                }

                if (i==0) {
                    token = tokens[i];
                    if (token.start != -1 && token.end == -1) {
                        parser.toksuper = uint128(i);
                    }
                }
                continue;
            }

            // 0x42
            if (c == '"') {
                Info('Double quote');
                r = parseString(parser, tokens, s);
                if (r < 0) return JsmnError.INVALID;
                count++;
				if (parser.toksuper != -1)
					tokens[uint(parser.toksuper)].size++;
                continue;
            }

            // ' ', \r, \t, \n
            if (c == ' ' || c == 0x11 || c == 0x12 || c == 0x14) {
                Info('Whitespace');
                continue;
            }

            // 0x3a
            if (c == ':') {
                Info('Colon');
                parser.toksuper = int(parser.toknext -1);
                continue;
            }

            if (c == ',') {
                Info('Comma');
                if (parser.toksuper != -1
                    && tokens[uint(parser.toksuper)].jsmnType != JsmnType.ARRAY
                    && tokens[uint(parser.toksuper)].jsmnType != JsmnType.OBJECT) {
                        for(i = parser.toknext-1; i>=0; i--) {
                            if (tokens[i].jsmnType == JsmnType.ARRAY || tokens[i].jsmnType == JsmnType.OBJECT) {
                                if (tokens[i].start != -1 && tokens[i].end == -1) {
                                    parser.toksuper = int(i);
                                    break;
                                }
                            }
                        }
                    }
                continue;
            }

            if ((c >= '0' && c <= '9') || c == 'f' || c == 't' || c == 'n') {
                Info('Primitive');
                if (parser.toksuper != -1) {
                    token = tokens[uint(parser.toksuper)];
                    if (token.jsmnType == JsmnType.OBJECT
                        || (token.jsmnType == JsmnType.STRING && token.size != 0)) {
                            return JsmnError.INVALID;
                        }
                }

                r = parsePrimitive(parser, tokens, s);
                if (r < 0) { return JsmnError.INVALID; }
                count++;
                if (parser.toksuper != -1) {
                    tokens[uint(parser.toksuper)].size++;
                }
                continue;
            }

            if (c >= 0x20 && c <= 0x7e) {
                Info('Printable char');
                continue;
            }
        }

        storageTokens.length = 0;
        for (i=0; i<parser.toknext; i++) {
            storageTokens.push(tokens[i]);
        }
    }

    function getAllTokens() {
        for (uint i=0; i<storageTokens.length; i++) {
            JsmnToken t = storageTokens[i];
            TokenInfo(t.jsmnType, t.start, t.end, t.size);
        }
    }

    function bytes32ToString(bytes32 x) constant returns (string) {
        bytes memory bytesString = new bytes(32);
        uint charCount = 0;
        for (uint j = 0; j < 32; j++) {
            byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
            if (char != 0) {
                bytesString[charCount] = char;
                charCount++;
            }
        }
        bytes memory bytesStringTrimmed = new bytes(charCount);
        for (j = 0; j < charCount; j++) {
            bytesStringTrimmed[j] = bytesString[j];
        }
        return string(bytesStringTrimmed);
    }

}

pragma solidity ^0.4.2;

contract JsmnSol {

    event Info(string msg);
    event TokenInfo(JsmnType jsmnType, int start, int end, uint8 size);
    event Debug(int toksuper, int length);

    enum JsmnType { UNDEFINED, OBJECT, ARRAY, STRING, PRIMITIVE }
    enum JsmnError { INVALID, ERROR_PART }

    struct JsmnToken {
        JsmnType jsmnType;
        int start;
        int end;
        uint8 size;
    }

    struct Parser {
        uint pos;
        uint toknext;
        int toksuper;
    }

    JsmnToken[] storageTokens;

    function jsmnInit(uint length) internal returns (Parser, JsmnToken[]) {
        Parser memory p = Parser(0, 0, -1);
        JsmnToken[] memory t = new JsmnToken[](length);
        return (p, t);
    }

    function allocateToken(Parser parser, JsmnToken[] tokens) internal returns (bool, JsmnToken) {
        Info('allocateToken');
        if (parser.toknext >= tokens.length) {
            // no more space in tokens
            return (false, tokens[tokens.length-1]);
        }
        tokens[parser.toknext] = JsmnToken(JsmnType.UNDEFINED, -1, -1, 0);
        parser.toknext++;
        return (true, tokens[parser.toknext-1]);
    }

    function fillToken(JsmnToken token, JsmnType jsmnType, int start, int end) internal {
        token.jsmnType = jsmnType;
        token.start = start;
        token.end = end;
        token.size = 0;
    }

    function parseString(Parser parser, JsmnToken[] tokens, bytes s) internal returns (int) {
        uint start = parser.pos;
        uint ti;
        parser.pos++;

        for (; parser.pos<s.length; parser.pos++) {
            bytes1 c = s[parser.pos];

            // Quote -> end of string
            if (c == '"') {
                var (result, token) = allocateToken(parser, tokens);
                fillToken(token, JsmnType.STRING, int(start+1), int(parser.pos-1));
                return 0;
            }

            if (c == '\\') {
                // TODO handle escaped characters
            }
        }
        parser.pos = start;
        return int(JsmnError.ERROR_PART);
    }

    function parsePrimitive(Parser parser, JsmnToken[] tokens, bytes s) internal returns (int) {
        bool found = false;
        uint start = parser.pos;
        byte c;
        uint ti;
        for (; parser.pos < s.length; parser.pos++) {
            c = s[parser.pos];
            if (c == ' ' || c == '\t' || c == '\n' || c == '\r' //|| c == ','
                || c == 0x7d || c == 0x5d) {
                    found = true;
                    break;
            }
            if (c < 32 || c > 127) {
                parser.pos = start;
                return int(JsmnError.INVALID);
            }
        }
        if (!found) {
            parser.pos = start;
            return int(JsmnError.ERROR_PART);
        }

        // found the end
        var (result, token) = allocateToken(parser, tokens);
        fillToken(token, JsmnType.PRIMITIVE, int(start), int(parser.pos));
        parser.pos--;
        return 0;
    }

    function jsmnParse(string json, uint numberElements) returns (JsmnError) {
        bytes memory s = bytes(json);
        var (parser, tokens) = jsmnInit(numberElements);

        // JsmnToken memory token;
        int r;
        uint ti;
        uint count = parser.toknext;
        uint i;

        for (; parser.pos<s.length; parser.pos++) {
            bytes1 c = s[parser.pos];

            // 0x7b, 0x5b opening parentheses
            if (c == 0x7b || c == 0x5b) {
                Info('Opening parentheses');
                count++;
                //token = allocateToken();
                var (result, token)= allocateToken(parser, tokens);
                if (parser.toksuper != -1) {
                    tokens[uint(parser.toksuper)].size++;
                }
                token.jsmnType = (c == 0x7b ? JsmnType.OBJECT : JsmnType.ARRAY);
                token.start = int(parser.pos);
                parser.toksuper = int(parser.toknext - 1);
                continue;
            }

            // closing parentheses
            if (c == 0x7d || c == 0x5d) {
                Info('Closing parentheses');
                JsmnType tokenType = (c == 0x7d ? JsmnType.OBJECT : JsmnType.ARRAY);
                bool isUpdated = false;
                for (i=parser.toknext; i>=0; i--) {
                    //token = tokens[uint(i)];
                    if (tokens[i].start != -1 && tokens[i].end == -1) {
                        if (tokens[i].jsmnType != tokenType) {
                            // found a token that hasn't been closed but from a different type
                            Info('Error: wrong type');
                            return JsmnError.INVALID;
                        }
                        parser.toksuper = -1;
                        tokens[i].end = int(parser.pos);
                        isUpdated = true;
                        break;
                    }
                }
                if (!isUpdated) {
                    Info('Error: No update');
                    return JsmnError.INVALID;
                }
                for (; i>0; i--) {
                    //token = tokens[uint(i)];
                    if (tokens[i].start != -1 && tokens[i].end == -1) {
                        parser.toksuper = uint128(i);
                        break;
                    }
                }

                if (i==0) {
                    if (tokens[i].start != -1 && tokens[i].end == -1) {
                        parser.toksuper = uint128(i);
                    }
                }
                continue;
            }

            // 0x42
            if (c == '"') {
                Info('Double quote');
                r = parseString(parser, tokens, s);
                if (r < 0) return JsmnError.INVALID;
                count++;
				if (parser.toksuper != -1)
					tokens[uint(parser.toksuper)].size++;
                continue;
            }

            // ' ', \r, \t, \n
            if (c == ' ' || c == 0x11 || c == 0x12 || c == 0x14) {
                Info('Whitespace');
                continue;
            }

            // 0x3a
            if (c == ':') {
                Info('Colon');
                parser.toksuper = int(parser.toknext -1);
                continue;
            }

            if (c == ',') {
                Info('Comma');
                if (parser.toksuper != -1
                    && tokens[uint(parser.toksuper)].jsmnType != JsmnType.ARRAY
                    && tokens[uint(parser.toksuper)].jsmnType != JsmnType.OBJECT) {
                        for(i = parser.toknext-1; i>=0; i--) {
                            if (tokens[i].jsmnType == JsmnType.ARRAY || tokens[i].jsmnType == JsmnType.OBJECT) {
                                if (tokens[i].start != -1 && tokens[i].end == -1) {
                                    parser.toksuper = int(i);
                                }
                            }
                        }
                    }
                continue;
            }

            if ((c >= '0' && c <= '9') || c == 'f' || c == 't' || c == 'n') {
                Info('Primitive');
                if (parser.toksuper != -1) {
                    if (tokens[uint(parser.toksuper)].jsmnType == JsmnType.OBJECT
                        || (tokens[uint(parser.toksuper)].jsmnType == JsmnType.STRING
                            && tokens[uint(parser.toksuper)].size != 0)) {
                            return JsmnError.INVALID;
                        }
                }

                parsePrimitive(parser, tokens, s);

                continue;
            }

            if (c >= 0x20 && c <= 0x7e) {
                Info('Printable char');
                continue;
            }
        }

        for (i=0; i<parser.toknext; i++) {
            storageTokens.push(tokens[i]);
        }
    }

    function getAllTokens() {
        for (uint i=0; i<storageTokens.length; i++) {
            JsmnToken t = storageTokens[i];
            TokenInfo(t.jsmnType, t.start, t.end, t.size);
        }
    }

    function bytes32ToString(bytes32 x) constant returns (string) {
        bytes memory bytesString = new bytes(32);
        uint charCount = 0;
        for (uint j = 0; j < 32; j++) {
            byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
            if (char != 0) {
                bytesString[charCount] = char;
                charCount++;
            }
        }
        bytes memory bytesStringTrimmed = new bytes(charCount);
        for (j = 0; j < charCount; j++) {
            bytesStringTrimmed[j] = bytesString[j];
        }
        return string(bytesStringTrimmed);
    }

}


allow incentivisationFundAddress to transfer during the ICO

pragma solidity ^0.4.15;
import './ERC20Token.sol';
import './Owned.sol';

contract ENJToken is ERC20Token, Owned {

///////////////////////////////////////// VARIABLE INITIALIZATION /////////////////////////////////////////

    uint256 public totalSupply = 1 * (10**9) * 10**18;

    //  Constants
    uint256 public maxPresaleSupply = 600 * 10**6 * 10**18;           // Total presale supply at max bonus
    uint256 public minCrowdsaleAllocation = 200 * 10**6 * 10**18;     // Min amount for crowdsale
    uint256 public incentivisationAllocation = 100 * 10**6 * 10**18;  // Incentivisation Allocation
    uint256 public advisorsAllocation = 50 * 10**6 * 10**18;          // Advisors Allocation
    uint256 public enjinTeamAllocation = 50 * 10**6 * 10**18;         // Enjin Team allocation

    address public crowdFundAddress;                                  // Address of the crowdfund
    address public advisorAddress;                                    // Enjin advisor's address
    address public incentivisationFundAddress;                        // Address that holds the incentivization funds

    //  Variables
    uint256 public totalAllocatedToAdvisors = 0;                      // Counter to keep track of total Advisor allocation
    uint256 public totalAllocatedToTeam = 0;                          // Counter to keep track of team token allocation
    uint256 public totalAllocated = 0;                                // Counter to keep track of team token allocation
    uint256 public startTime = 1507032000;                            // 10/03/2017 @ 12:00pm (UTC) crowdsale start time (in seconds)
    uint256 public endTime = 1509494340;                              // 10/31/2017 @ 11:59pm (UTC) crowdsale end time (in seconds)

    bool internal isReleasedToPublic = false;                         // Flag to allow transfer/transferFrom before the end of the crowdfund

    bool internal releaseFirstAllocationTranche = false;              // Flags to keep track of Team allocation tranches
    bool internal releaseSecondAllocationTranche = false;             // Flags to keep track of Team allocation tranches
    bool internal releaseThirdAllocationTranche = false;              // Flags to keep track of Team allocation tranches
    bool internal releaseFourthAllocationTranche = false;             // Flags to keep track of Team allocation tranches
    bool internal releaseFifthAllocationTranche = false;              // Flags to keep track of Team allocation tranches
    bool internal releaseSixthAllocationTranche = false;              // Flags to keep track of Team allocation tranches
    bool internal releaseSeventhAllocationTranche = false;            // Flags to keep track of Team allocation tranches

///////////////////////////////////////// MODIFIERS /////////////////////////////////////////

    // Enjin Team timelock
    modifier safeTimelock() {
        require(now >= endTime + 6 * 4 weeks);
        _;
    }

    // Advisor Team timelock
    modifier advisorTimelock() {
        require(now >= endTime + 2 * 4 weeks);
        _;
    }

    // Function only accessible by the Advisor address
    modifier advisorOnly() {
        require(msg.sender == advisorAddress);
        _;
    }

    // Function only accessible by the Crowdfund contract
    modifier crowdfundOnly() {
        require(msg.sender == crowdFundAddress);
        _;
    }

    ///////////////////////////////////////// CONSTRUCTOR /////////////////////////////////////////

    /**
        @dev constructor
        @param _crowdFundAddress   Crowdfund address
        @param _advisorAddress     Advisor address
    */
    function ENJToken(address _crowdFundAddress, address _advisorAddress, address _incentivisationFundAddress)
    ERC20Token("ENJ Coin", "ENJ", 18)
     {
        crowdFundAddress = _crowdFundAddress;
        advisorAddress = _advisorAddress;
        incentivisationFundAddress = _incentivisationFundAddress;
        balanceOf[_crowdFundAddress] = minCrowdsaleAllocation + maxPresaleSupply; // Total presale + crowdfund tokens
        balanceOf[_incentivisationFundAddress] = incentivisationAllocation;       // 10% Allocated for Marketing and Incentivisation
        totalAllocated += incentivisationAllocation;                              // Add to total Allocated funds
    }

///////////////////////////////////////// ERC20 OVERRIDE /////////////////////////////////////////

    /**
        @dev send coins
        throws on any error rather then return a false flag to minimize user errors
        in addition to the standard checks, the function throws if transfers are disabled

        @param _to      target address
        @param _value   transfer amount

        @return true if the transfer was successful, throws if it wasn't
    */
    function transfer(address _to, uint256 _value) greaterThanZero(_value) public returns (bool success) {
        if (isTransferAllowed() == true || msg.sender == crowdFundAddress || msg.sender == incentivisationFundAddress) {
            assert(super.transfer(_to, _value));
            return true;
        }
        revert();
    }

    /**
        @dev an account/contract attempts to get the coins
        throws on any error rather then return a false flag to minimize user errors
        in addition to the standard checks, the function throws if transfers are disabled

        @param _from    source address
        @param _to      target address
        @param _value   transfer amount

        @return true if the transfer was successful, throws if it wasn't
    */
    function transferFrom(address _from, address _to, uint256 _value) greaterThanZero(_value) public returns (bool success) {
        if (isTransferAllowed() == true || msg.sender == crowdFundAddress || msg.sender == incentivisationFundAddress) {
            assert(super.transferFrom(_from, _to, _value));
            return true;
        }
        revert();
    }

///////////////////////////////////////// ALLOCATION FUNCTIONS /////////////////////////////////////////

    /**
        @dev release Enjin Team Token allocation
        throws if before timelock (6 months) ends and if no initiated by the owner of the contract
        returns true if valid
        Schedule goes as follows:
        6 months: 25%
        9 months: 12.5%
        12 months: 12.5%
        15 months: 12.5%
        18 months: 12.5%
        21 months: 12.5%
        24 months: 12.5%
        @return true if successful, throws if not
    */
    function releaseEnjinTeamTokens() ownerOnly returns(bool success) {
        require(totalAllocatedToTeam < enjinTeamAllocation);
        uint256 enjinTeamAlloc = enjinTeamAllocation / 1000;

        if (now > endTime + 6 * 4 weeks && !releaseFirstAllocationTranche) {
            releaseFirstAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 250));
            return true;
        } else  if (now > endTime + 9 * 4 weeks && !releaseSecondAllocationTranche) {
            releaseSecondAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 125));
            return true;
        } else  if (now > endTime + 12 * 4 weeks && !releaseThirdAllocationTranche) {
            releaseThirdAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 125));
            return true;
        } else  if (now > endTime + 15 * 4 weeks && !releaseFourthAllocationTranche) {
            releaseFourthAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 125));
            return true;
        } else  if (now > endTime + 18 * 4 weeks && !releaseFifthAllocationTranche) {
            releaseFifthAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 125));
            return true;
        } else  if (now > endTime + 21 * 4 weeks && !releaseSixthAllocationTranche) {
            releaseSixthAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 125));
            return true;
        } else  if (now > endTime + 24 * 4 weeks && !releaseSeventhAllocationTranche) {
            releaseSeventhAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 125));
            return true;
        }
        revert();
    }

    /**
        @dev transfers Tokens from Enjin allocation to Team
        throws if before first timelock (6 months) ends and if no initiated by the owner of the contract
        @return true if successful, throws if not
    */
    function transferTeamAllocation(uint256 _amount) ownerOnly internal {
        balanceOf[msg.sender] = safeAdd(balanceOf[msg.sender], _amount);
        Transfer(this, msg.sender, _amount);
        totalAllocated = safeAdd(totalAllocated, _amount);
        totalAllocatedToTeam = safeAdd(totalAllocatedToTeam, _amount);
    }

    /**
        @dev release Advisors Token allocation
        throws if before timelock (2 months) ends or if no initiated by the advisors address
        or if there is no more allocation to give out
        returns true if valid

        @return true if successful, throws if not
    */
    function releaseAdvisorTokens() advisorTimelock advisorOnly returns(bool success) {
        require(totalAllocatedToAdvisors == 0);
        balanceOf[msg.sender] = safeAdd(balanceOf[msg.sender], advisorsAllocation);
        Transfer(this, msg.sender, advisorsAllocation);
        totalAllocated = safeAdd(totalAllocated, advisorsAllocation);
        totalAllocatedToAdvisors = advisorsAllocation;
        return true;
    }

    /**
        @dev Retrive unsold tokens from the crowdfund
        throws if before timelock (6 months from end of Crowdfund) ends and if no initiated by the owner of the contract
        returns true if valid

        @return true if successful, throws if not
    */
    function retrieveUnsoldTokens() safeTimelock ownerOnly returns(bool success) {
        uint256 amountOfTokens = balanceOf[crowdFundAddress];
        balanceOf[msg.sender] = safeAdd(balanceOf[msg.sender], amountOfTokens);
        totalAllocated = safeAdd(totalAllocated, amountOfTokens);
        balanceOf[crowdFundAddress] = 0;
        return true;
    }

    /**
        @dev Keep track of token allocations
        can only be called by the crowdfund contract
    */
    function addToAllocation(uint256 _amount) crowdfundOnly {
        totalAllocated = safeAdd(totalAllocated, _amount);
    }

    /**
        @dev Function to allow transfers
        can only be called by the owner of the contract
        Transfers will be allowed regradless after the crowdfund end time.
    */
    function allowTransfers() ownerOnly {
        isReleasedToPublic = true;
    }

    /**
        @dev User transfers are allowed/rejected
        Transfers are forbidden before the end of the crowdfund
    */
    function isTransferAllowed() internal returns(bool) {
        if (now > endTime || isReleasedToPublic == true) {
            return true;
        }
        return false;
    }

    /**
        @dev
        Function to show the total Incentivisation tokens allocated
    */
    function totalAllocatedToIncentives() public constant returns(uint256) {
        return incentivisationAllocation - balanceOf[incentivisationFundAddress];
    }

    function () {
        revert();
    }
}

pragma solidity ^0.4.15;
import './ERC20Token.sol';
import './Owned.sol';

contract ENJToken is ERC20Token, Owned {

///////////////////////////////////////// VARIABLE INITIALIZATION /////////////////////////////////////////

    uint256 public totalSupply = 1 * (10**9) * 10**18;

    //  Constants
    uint256 public maxPresaleSupply = 600 * 10**6 * 10**18;           // Total presale supply at max bonus
    uint256 public minCrowdsaleAllocation = 200 * 10**6 * 10**18;     // Min amount for crowdsale
    uint256 public incentivisationAllocation = 100 * 10**6 * 10**18;  // Incentivisation Allocation
    uint256 public advisorsAllocation = 50 * 10**6 * 10**18;          // Advisors Allocation
    uint256 public enjinTeamAllocation = 50 * 10**6 * 10**18;         // Enjin Team allocation

    address public crowdFundAddress;                                  // Address of the crowdfund
    address public advisorAddress;                                    // Enjin advisor's address
    address public incentivisationFundAddress;                        // Address that holds the incentivization funds

    //  Variables
    uint256 public totalAllocatedToAdvisors = 0;                      // Counter to keep track of total Advisor allocation
    uint256 public totalAllocatedToTeam = 0;                          // Counter to keep track of team token allocation
    uint256 public totalAllocated = 0;                                // Counter to keep track of team token allocation
    uint256 public startTime = 1507032000;                            // 10/03/2017 @ 12:00pm (UTC) crowdsale start time (in seconds)
    uint256 public endTime = 1509494340;                              // 10/31/2017 @ 11:59pm (UTC) crowdsale end time (in seconds)

    bool internal isReleasedToPublic = false;                         // Flag to allow transfer/transferFrom before the end of the crowdfund

    bool internal releaseFirstAllocationTranche = false;              // Flags to keep track of Team allocation tranches
    bool internal releaseSecondAllocationTranche = false;             // Flags to keep track of Team allocation tranches
    bool internal releaseThirdAllocationTranche = false;              // Flags to keep track of Team allocation tranches
    bool internal releaseFourthAllocationTranche = false;             // Flags to keep track of Team allocation tranches
    bool internal releaseFifthAllocationTranche = false;              // Flags to keep track of Team allocation tranches
    bool internal releaseSixthAllocationTranche = false;              // Flags to keep track of Team allocation tranches
    bool internal releaseSeventhAllocationTranche = false;            // Flags to keep track of Team allocation tranches

///////////////////////////////////////// MODIFIERS /////////////////////////////////////////

    // Enjin Team timelock
    modifier safeTimelock() {
        require(now >= endTime + 6 * 4 weeks);
        _;
    }

    // Advisor Team timelock
    modifier advisorTimelock() {
        require(now >= endTime + 2 * 4 weeks);
        _;
    }

    // Function only accessible by the Advisor address
    modifier advisorOnly() {
        require(msg.sender == advisorAddress);
        _;
    }

    // Function only accessible by the Crowdfund contract
    modifier crowdfundOnly() {
        require(msg.sender == crowdFundAddress);
        _;
    }

    ///////////////////////////////////////// CONSTRUCTOR /////////////////////////////////////////

    /**
        @dev constructor
        @param _crowdFundAddress   Crowdfund address
        @param _advisorAddress     Advisor address
    */
    function ENJToken(address _crowdFundAddress, address _advisorAddress, address _incentivisationFundAddress)
    ERC20Token("ENJ Coin", "ENJ", 18)
     {
        crowdFundAddress = _crowdFundAddress;
        advisorAddress = _advisorAddress;
        incentivisationFundAddress = _incentivisationFundAddress;
        balanceOf[_crowdFundAddress] = minCrowdsaleAllocation + maxPresaleSupply; // Total presale + crowdfund tokens
        balanceOf[_incentivisationFundAddress] = incentivisationAllocation;       // 10% Allocated for Marketing and Incentivisation
        totalAllocated += incentivisationAllocation;                              // Add to total Allocated funds
    }

///////////////////////////////////////// ERC20 OVERRIDE /////////////////////////////////////////

    /**
        @dev send coins
        throws on any error rather then return a false flag to minimize user errors
        in addition to the standard checks, the function throws if transfers are disabled

        @param _to      target address
        @param _value   transfer amount

        @return true if the transfer was successful, throws if it wasn't
    */
    function transfer(address _to, uint256 _value) greaterThanZero(_value) public returns (bool success) {
        if (isTransferAllowed() == true || msg.sender == crowdFundAddress) {
            assert(super.transfer(_to, _value));
            return true;
        }
        revert();
    }

    /**
        @dev an account/contract attempts to get the coins
        throws on any error rather then return a false flag to minimize user errors
        in addition to the standard checks, the function throws if transfers are disabled

        @param _from    source address
        @param _to      target address
        @param _value   transfer amount

        @return true if the transfer was successful, throws if it wasn't
    */
    function transferFrom(address _from, address _to, uint256 _value) greaterThanZero(_value) public returns (bool success) {
        if (isTransferAllowed() == true || msg.sender == crowdFundAddress) {
            assert(super.transferFrom(_from, _to, _value));
            return true;
        }
        revert();
    }

///////////////////////////////////////// ALLOCATION FUNCTIONS /////////////////////////////////////////

    /**
        @dev release Enjin Team Token allocation
        throws if before timelock (6 months) ends and if no initiated by the owner of the contract
        returns true if valid
        Schedule goes as follows:
        6 months: 25%
        9 months: 12.5%
        12 months: 12.5%
        15 months: 12.5%
        18 months: 12.5%
        21 months: 12.5%
        24 months: 12.5%
        @return true if successful, throws if not
    */
    function releaseEnjinTeamTokens() ownerOnly returns(bool success) {
        require(totalAllocatedToTeam < enjinTeamAllocation);
        uint256 enjinTeamAlloc = enjinTeamAllocation / 1000;

        if (now > endTime + 6 * 4 weeks && !releaseFirstAllocationTranche) {
            releaseFirstAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 250));
            return true;
        } else  if (now > endTime + 9 * 4 weeks && !releaseSecondAllocationTranche) {
            releaseSecondAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 125));
            return true;
        } else  if (now > endTime + 12 * 4 weeks && !releaseThirdAllocationTranche) {
            releaseThirdAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 125));
            return true;
        } else  if (now > endTime + 15 * 4 weeks && !releaseFourthAllocationTranche) {
            releaseFourthAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 125));
            return true;
        } else  if (now > endTime + 18 * 4 weeks && !releaseFifthAllocationTranche) {
            releaseFifthAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 125));
            return true;
        } else  if (now > endTime + 21 * 4 weeks && !releaseSixthAllocationTranche) {
            releaseSixthAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 125));
            return true;
        } else  if (now > endTime + 24 * 4 weeks && !releaseSeventhAllocationTranche) {
            releaseSeventhAllocationTranche = true;
            transferTeamAllocation(safeMul(enjinTeamAlloc, 125));
            return true;
        }
        revert();
    }

    /**
        @dev transfers Tokens from Enjin allocation to Team
        throws if before first timelock (6 months) ends and if no initiated by the owner of the contract
        @return true if successful, throws if not
    */
    function transferTeamAllocation(uint256 _amount) ownerOnly internal {
        balanceOf[msg.sender] = safeAdd(balanceOf[msg.sender], _amount);
        Transfer(this, msg.sender, _amount);
        totalAllocated = safeAdd(totalAllocated, _amount);
        totalAllocatedToTeam = safeAdd(totalAllocatedToTeam, _amount);
    }

    /**
        @dev release Advisors Token allocation
        throws if before timelock (2 months) ends or if no initiated by the advisors address
        or if there is no more allocation to give out
        returns true if valid

        @return true if successful, throws if not
    */
    function releaseAdvisorTokens() advisorTimelock advisorOnly returns(bool success) {
        require(totalAllocatedToAdvisors == 0);
        balanceOf[msg.sender] = safeAdd(balanceOf[msg.sender], advisorsAllocation);
        Transfer(this, msg.sender, advisorsAllocation);
        totalAllocated = safeAdd(totalAllocated, advisorsAllocation);
        totalAllocatedToAdvisors = advisorsAllocation;
        return true;
    }

    /**
        @dev Retrive unsold tokens from the crowdfund
        throws if before timelock (6 months from end of Crowdfund) ends and if no initiated by the owner of the contract
        returns true if valid

        @return true if successful, throws if not
    */
    function retrieveUnsoldTokens() safeTimelock ownerOnly returns(bool success) {
        uint256 amountOfTokens = balanceOf[crowdFundAddress];
        balanceOf[msg.sender] = safeAdd(balanceOf[msg.sender], amountOfTokens);
        totalAllocated = safeAdd(totalAllocated, amountOfTokens);
        balanceOf[crowdFundAddress] = 0;
        return true;
    }

    /**
        @dev Keep track of token allocations
        can only be called by the crowdfund contract
    */
    function addToAllocation(uint256 _amount) crowdfundOnly {
        totalAllocated = safeAdd(totalAllocated, _amount);
    }

    /**
        @dev Function to allow transfers
        can only be called by the owner of the contract
        Transfers will be allowed regradless after the crowdfund end time.
    */
    function allowTransfers() ownerOnly {
        isReleasedToPublic = true;
    }

    /**
        @dev User transfers are allowed/rejected
        Transfers are forbidden before the end of the crowdfund
    */
    function isTransferAllowed() internal returns(bool) {
        if (now > endTime || isReleasedToPublic == true) {
            return true;
        }
        return false;
    }

    /**
        @dev
        Function to show the total Incentivisation tokens allocated
    */
    function totalAllocatedToIncentives() public constant returns(uint256) {
        return incentivisationAllocation - balanceOf[incentivisationFundAddress];
    }

    function () {
        revert();
    }
}


change check to greater than or equal to in subtractBalance

pragma solidity ^0.4.0;

import "./Concept.sol";
import "./User.sol";
import "./ConceptRegistry.sol";

/*
@type: contract
@name: UserRegistry
@purpose: To store data about users for easy and secure access
*/
contract UserRegistry {
  address public conceptRegistry; //The address of the conceptRegistry contract
  mapping (address => uint) public balances; //Maps the addresses of users to their token balances
  mapping (address => address) public users; //Maps the addresses of the users to their account
  bool firstUserMade = false; //Keeps track of whether or not the first user has been made yet
  event UserCreation(address _userAddress); //address of the created user contract

  modifier onlyConcept() {
    if(ConceptRegistry(conceptRegistry).conceptExists(msg.sender) == false) //checks if the address calling the function is not a concept
    {
      throw; //throws out the fucntion call
    }
    _;
  }

  modifier onlyThis() {
    if(msg.sender != address(this))
    {
      throw;
    }
    _;
  }

  //Constructor
  function UserRegistry(address _conceptRegistry) {
    conceptRegistry = _conceptRegistry;
  }

  /*
  @type: function
  @purpose: To create a user contract
  @param: address userAddress = the address of the user's wallet
  @param: address masterAddress = the address of the master contract that stores this user's address
  @returns: nothing
  */
  function addUser(address userAddress) {
    User newUser = new User(userAddress, address(this)); //Makes a new user that represents the address from userAddress and uses the master from masterAddress as its datastore
    Concept(ConceptRegistry(conceptRegistry).mewAddress()).addUser(address(newUser));
    users[userAddress] = newUser;
    UserCreation(address(newUser)); //Makes a new UserCreation event with the address of the newly created user
  }

  function firstUser(address userAddress) {
    if(firstUserMade == false) {
      User newUser = new User(userAddress, address(this)); //Makes a new user that represents the address from userAddress
      Concept(ConceptRegistry(conceptRegistry).mewAddress()).addUser(address(newUser));
      users[userAddress] = newUser;
      balances[newUser] = 1000;
      UserCreation(address(newUser)); //Makes a new UserCreation event with the address of the newly created user
    }
  }

  function addBalance(address _to, uint _amount) onlyConcept() returns(bool) {
    if(balances[_to] + _amount > balances[_to]){
      balances[_to] += _amount;
      return true;
    }
    else {
      return false;
    }
  }

  function subtractBalance(address _from, uint _amount) onlyConcept() returns(bool) {
    if(balances[_from] >= _amount){
      balances[_from] -= _amount;
      return true;
    }
    return false;
  }

  function transfer(address _to, uint _amount) returns(bool) {
    if(balances[msg.sender] > _amount &&
       balances[_to] + _amount > balances[_to]) {
      balances[msg.sender] -= _amount;
      balances[_to] += _amount;
      return true;
    }
    else {
      return false;
    }
  }

  function remove(address reciever) onlyThis() {
    suicide(reciever);
  }
}

pragma solidity ^0.4.0;

import "./Concept.sol";
import "./User.sol";
import "./ConceptRegistry.sol";

/*
@type: contract
@name: UserRegistry
@purpose: To store data about users for easy and secure access
*/
contract UserRegistry {
  address public conceptRegistry; //The address of the conceptRegistry contract
  mapping (address => uint) public balances; //Maps the addresses of users to their token balances
  mapping (address => address) public users; //Maps the addresses of the users to their account
  bool firstUserMade = false; //Keeps track of whether or not the first user has been made yet
  event UserCreation(address _userAddress); //address of the created user contract

  modifier onlyConcept() {
    if(ConceptRegistry(conceptRegistry).conceptExists(msg.sender) == false) //checks if the address calling the function is not a concept
    {
      throw; //throws out the fucntion call
    }
    _;
  }

  modifier onlyThis() {
    if(msg.sender != address(this))
    {
      throw;
    }
    _;
  }

  //Constructor
  function UserRegistry(address _conceptRegistry) {
    conceptRegistry = _conceptRegistry;
  }

  /*
  @type: function
  @purpose: To create a user contract
  @param: address userAddress = the address of the user's wallet
  @param: address masterAddress = the address of the master contract that stores this user's address
  @returns: nothing
  */
  function addUser(address userAddress) {
    User newUser = new User(userAddress, address(this)); //Makes a new user that represents the address from userAddress and uses the master from masterAddress as its datastore
    Concept(ConceptRegistry(conceptRegistry).mewAddress()).addUser(address(newUser));
    users[userAddress] = newUser;
    UserCreation(address(newUser)); //Makes a new UserCreation event with the address of the newly created user
  }

  function firstUser(address userAddress) {
    if(firstUserMade == false) {
      User newUser = new User(userAddress, address(this)); //Makes a new user that represents the address from userAddress
      Concept(ConceptRegistry(conceptRegistry).mewAddress()).addUser(address(newUser));
      users[userAddress] = newUser;
      balances[newUser] = 1000;
      UserCreation(address(newUser)); //Makes a new UserCreation event with the address of the newly created user
    }
  }

  function addBalance(address _to, uint _amount) onlyConcept() returns(bool) {
    if(balances[_to] + _amount > balances[_to]){
      balances[_to] += _amount;
      return true;
    }
    else {
      return false;
    }
  }

  function subtractBalance(address _from, uint _amount) onlyConcept() returns(bool) {
    if(balances[_from] > _amount){
      balances[_from] -= _amount;
      return true;
    }
    return false;
  }

  function transfer(address _to, uint _amount) returns(bool) {
    if(balances[msg.sender] > _amount &&
       balances[_to] + _amount > balances[_to]) {
      balances[msg.sender] -= _amount;
      balances[_to] += _amount;
      return true;
    }
    else {
      return false;
    }
  }

  function remove(address reciever) onlyThis() {
    suicide(reciever);
  }
}


Added lighthouse name reservation check

Added lighthouse name reservation check

pragma solidity ^0.4.24;

import './RobotLiability.sol';
import './Lighthouse.sol';
import './XRT.sol';

import 'ens/contracts/ENS.sol';
import 'ens/contracts/ENSRegistry.sol';
import 'ens/contracts/PublicResolver.sol';

contract LiabilityFactory {
    constructor(
        address _robot_liability_lib,
        address _lighthouse_lib,
        XRT _xrt
    ) public {
        robotLiabilityLib = _robot_liability_lib;
        lighthouseLib = _lighthouse_lib;
        xrt = _xrt;
    }

    /**
     * @dev New liability created
     */
    event NewLiability(address indexed liability);

    /**
     * @dev New lighthouse created
     */
    event NewLighthouse(address indexed lighthouse, string name);

    /**
     * @dev Robonomics network protocol token
     */
    XRT public xrt;

    /**
     * @dev Ethereum name system
     */
    ENS public ens;

    /**
     * @dev Robonomics ENS resolver
     */
    PublicResolver public resolver;

    bytes32 constant lighthouseNode
        // lighthouse.0.robonomics.eth
        = 0x1e42a8e8e1e8cf36e83d096dcc74af801d0a194a14b897f9c8dfd403b4eebeda;

    /**
     *  @dev Set ENS registry contract address
     */
    function setENS(ENS _ens) public {
      require(address(ens) == 0);
      ens = _ens;
      resolver = PublicResolver(ens.resolver(lighthouseNode));
    }

    /**
     * @dev Total GAS utilized by Robonomics network
     */
    uint256 public totalGasUtilizing = 0;

    /**
     * @dev GAS utilized by liability contracts
     */
    mapping(address => uint256) public gasUtilizing;

    /**
     * @dev Used market orders accounting
     */
    mapping(bytes32 => bool) public usedHash;

    /**
     * @dev Lighthouse accounting
     */
    mapping(address => bool) public isLighthouse;

    /**
     * @dev Robot liability shared code smart contract
     */
    address public robotLiabilityLib;

    /**
     * @dev Lightouse shared code smart contract
     */
    address public lighthouseLib;

    /**
     * @dev XRT emission value for utilized gas
     */
    function winnerFromGas(uint256 _gas) public view returns (uint256) {
        // Basic equal formula
        uint256 wn = _gas;

        /* Additional emission table */
        if (totalGasUtilizing < 856368000) {
            wn *= 37;
        } else if (totalGasUtilizing < 856368000 * 2) {
            wn *= 25;
        } else if (totalGasUtilizing < 856368000 * 3) {
            wn *= 17;
        } else if (totalGasUtilizing < 856368000 * 4) {
            wn *= 11;
        } else if (totalGasUtilizing < 856368000 * 5) {
            wn *= 7;
        } else if (totalGasUtilizing < 856368000 * 6) {
            wn *= 5;
        } else if (totalGasUtilizing < 856368000 * 7) {
            wn *= 3;
        } else if (totalGasUtilizing < 856368000 * 8) {
            wn *= 2;
        }

        return wn ;
    }

    /**
     * @dev Only lighthouse guard
     */
    modifier onlyLighthouse {
        require(isLighthouse[msg.sender]);
        _;
    }

    /**
     * @dev Parameter can be used only once
     * @param _hash Single usage hash
     */
    function usedHashGuard(bytes32 _hash) internal {
        require(!usedHash[_hash]);
        usedHash[_hash] = true;
    }

    /**
     * @dev Create robot liability smart contract
     * @param _ask ABI-encoded ASK order message
     * @param _bid ABI-encoded BID order message
     */
    function createLiability(
        bytes _ask,
        bytes _bid
    )
        external
        onlyLighthouse
        returns (RobotLiability liability)
    {
        // Store in memory available gas
        uint256 gasinit = gasleft();

        // Create liability
        liability = new RobotLiability(robotLiabilityLib);
        emit NewLiability(liability);

        // Parse messages
        require(liability.call(abi.encodePacked(bytes4(0x82fbaa25), _ask))); // liability.ask(...)
        usedHashGuard(liability.askHash());

        require(liability.call(abi.encodePacked(bytes4(0x66193359), _bid))); // liability.bid(...)
        usedHashGuard(liability.bidHash());

        // Transfer lighthouse fee to lighthouse worker directly
        require(xrt.transferFrom(liability.promisor(),
                                 tx.origin,
                                 liability.lighthouseFee()));

        // Transfer liability security and hold on contract
        ERC20 token = liability.token();
        require(token.transferFrom(liability.promisee(),
                                   liability,
                                   liability.cost()));

        // Transfer validator fee and hold on contract
        if (address(liability.validator()) != 0 && liability.validatorFee() > 0)
            require(xrt.transferFrom(liability.promisee(),
                                     liability,
                                     liability.validatorFee()));

        // Accounting gas usage of transaction
        uint256 gas = gasinit - gasleft() + 120525; // Including observation error
        totalGasUtilizing       += gas;
        gasUtilizing[liability] += gas;
     }

    /**
     * @dev Create lighthouse smart contract
     * @param _minimalFreeze Minimal freeze value of XRT token
     * @param _timeoutBlocks Max time of lighthouse silence in blocks
     * @param _name Lighthouse subdomain,
     *              example: for 'my-name' will created 'my-name.lighthouse.0.robonomics.eth' domain
     */
    function createLighthouse(
        uint256 _minimalFreeze,
        uint256 _timeoutBlocks,
        string  _name
    )
        external
        returns (address lighthouse)
    {
        // Name reservation check
        bytes32 subnode = keccak256(abi.encodePacked(lighthouseNode, keccak256(_name)));
        require(ens.resolver(subnode) == 0);

        // Create lighthouse
        lighthouse = new Lighthouse(lighthouseLib, _minimalFreeze, _timeoutBlocks);
        emit NewLighthouse(lighthouse, _name);
        isLighthouse[lighthouse] = true;

        // Register subnode
        ens.setSubnodeOwner(lighthouseNode, keccak256(_name), this);

        // Register lighthouse address
        ens.setResolver(subnode, resolver);
        resolver.setAddr(subnode, lighthouse);
    }

    /**
     * @dev Is called whan after liability finalization
     * @param _gas Liability finalization gas expenses
     */
    function liabilityFinalized(
        uint256 _gas
    )
        external
        returns (bool)
    {
        require(gasUtilizing[msg.sender] > 0);

        totalGasUtilizing        += _gas + 75801; // Including observation error
        gasUtilizing[msg.sender] += _gas + 75800; // Including observation error
        require(xrt.mint(tx.origin, winnerFromGas(gasUtilizing[msg.sender])));
        return true;
    }
}

pragma solidity ^0.4.24;

import './RobotLiability.sol';
import './Lighthouse.sol';
import './XRT.sol';

import 'ens/contracts/ENS.sol';
import 'ens/contracts/ENSRegistry.sol';
import 'ens/contracts/PublicResolver.sol';

contract LiabilityFactory {
    constructor(
        address _robot_liability_lib,
        address _lighthouse_lib,
        XRT _xrt
    ) public {
        robotLiabilityLib = _robot_liability_lib;
        lighthouseLib = _lighthouse_lib;
        xrt = _xrt;
    }

    /**
     * @dev New liability created
     */
    event NewLiability(address indexed liability);

    /**
     * @dev New lighthouse created
     */
    event NewLighthouse(address indexed lighthouse, string name);

    /**
     * @dev Robonomics network protocol token
     */
    XRT public xrt;

    /**
     * @dev Ethereum name system
     */
    ENS public ens;

    /**
     * @dev Robonomics ENS resolver
     */
    PublicResolver public resolver;

    bytes32 constant lighthouseNode
        // lighthouse.0.robonomics.eth
        = 0x1e42a8e8e1e8cf36e83d096dcc74af801d0a194a14b897f9c8dfd403b4eebeda;

    /**
     *  @dev Set ENS registry contract address
     */
    function setENS(ENS _ens) public {
      require(address(ens) == 0);
      ens = _ens;
      resolver = PublicResolver(ens.resolver(lighthouseNode));
    }

    /**
     * @dev Total GAS utilized by Robonomics network
     */
    uint256 public totalGasUtilizing = 0;

    /**
     * @dev GAS utilized by liability contracts
     */
    mapping(address => uint256) public gasUtilizing;

    /**
     * @dev Used market orders accounting
     */
    mapping(bytes32 => bool) public usedHash;

    /**
     * @dev Lighthouse accounting
     */
    mapping(address => bool) public isLighthouse;

    /**
     * @dev Robot liability shared code smart contract
     */
    address public robotLiabilityLib;

    /**
     * @dev Lightouse shared code smart contract
     */
    address public lighthouseLib;

    /**
     * @dev XRT emission value for utilized gas
     */
    function winnerFromGas(uint256 _gas) public view returns (uint256) {
        // Basic equal formula
        uint256 wn = _gas;

        /* Additional emission table */
        if (totalGasUtilizing < 856368000) {
            wn *= 37;
        } else if (totalGasUtilizing < 856368000 * 2) {
            wn *= 25;
        } else if (totalGasUtilizing < 856368000 * 3) {
            wn *= 17;
        } else if (totalGasUtilizing < 856368000 * 4) {
            wn *= 11;
        } else if (totalGasUtilizing < 856368000 * 5) {
            wn *= 7;
        } else if (totalGasUtilizing < 856368000 * 6) {
            wn *= 5;
        } else if (totalGasUtilizing < 856368000 * 7) {
            wn *= 3;
        } else if (totalGasUtilizing < 856368000 * 8) {
            wn *= 2;
        }

        return wn ;
    }

    /**
     * @dev Only lighthouse guard
     */
    modifier onlyLighthouse {
        require(isLighthouse[msg.sender]);
        _;
    }

    /**
     * @dev Parameter can be used only once
     * @param _hash Single usage hash
     */
    function usedHashGuard(bytes32 _hash) internal {
        require(!usedHash[_hash]);
        usedHash[_hash] = true;
    }

    /**
     * @dev Create robot liability smart contract
     * @param _ask ABI-encoded ASK order message
     * @param _bid ABI-encoded BID order message
     */
    function createLiability(
        bytes _ask,
        bytes _bid
    )
        external
        onlyLighthouse
        returns (RobotLiability liability)
    {
        // Store in memory available gas
        uint256 gasinit = gasleft();

        // Create liability
        liability = new RobotLiability(robotLiabilityLib);
        emit NewLiability(liability);

        // Parse messages
        require(liability.call(abi.encodePacked(bytes4(0x82fbaa25), _ask))); // liability.ask(...)
        usedHashGuard(liability.askHash());

        require(liability.call(abi.encodePacked(bytes4(0x66193359), _bid))); // liability.bid(...)
        usedHashGuard(liability.bidHash());

        // Transfer lighthouse fee to lighthouse worker directly
        require(xrt.transferFrom(liability.promisor(),
                                 tx.origin,
                                 liability.lighthouseFee()));

        // Transfer liability security and hold on contract
        ERC20 token = liability.token();
        require(token.transferFrom(liability.promisee(),
                                   liability,
                                   liability.cost()));

        // Transfer validator fee and hold on contract
        if (address(liability.validator()) != 0 && liability.validatorFee() > 0)
            require(xrt.transferFrom(liability.promisee(),
                                     liability,
                                     liability.validatorFee()));

        // Accounting gas usage of transaction
        uint256 gas = gasinit - gasleft() + 120525; // Including observation error
        totalGasUtilizing       += gas;
        gasUtilizing[liability] += gas;
     }

    /**
     * @dev Create lighthouse smart contract
     * @param _minimalFreeze Minimal freeze value of XRT token
     * @param _timeoutBlocks Max time of lighthouse silence in blocks
     * @param _name Lighthouse subdomain,
     *              example: for 'my-name' will created 'my-name.lighthouse.0.robonomics.eth' domain
     */
    function createLighthouse(
        uint256 _minimalFreeze,
        uint256 _timeoutBlocks,
        string  _name
    )
        external
        returns (address lighthouse)
    {
        // Create lighthouse
        lighthouse = new Lighthouse(lighthouseLib, _minimalFreeze, _timeoutBlocks);
        emit NewLighthouse(lighthouse, _name);
        isLighthouse[lighthouse] = true;

        // Register subnode
        ens.setSubnodeOwner(lighthouseNode, keccak256(_name), this);

        // Register lighthouse address
        bytes32 subnode = keccak256(abi.encodePacked(lighthouseNode, keccak256(_name)));
        ens.setResolver(subnode, resolver);
        resolver.setAddr(subnode, lighthouse);
    }

    /**
     * @dev Is called whan after liability finalization
     * @param _gas Liability finalization gas expenses
     */
    function liabilityFinalized(
        uint256 _gas
    )
        external
        returns (bool)
    {
        require(gasUtilizing[msg.sender] > 0);

        totalGasUtilizing        += _gas + 75801; // Including observation error
        gasUtilizing[msg.sender] += _gas + 75800; // Including observation error
        require(xrt.mint(tx.origin, winnerFromGas(gasUtilizing[msg.sender])));
        return true;
    }
}


updated comments

updated comments

/// @author hugooconnor
/// @title A shared account to demo some features of solidity, with standard tokens
/// see how to document solidity code; https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format

contract Access {

	/**
	 * Data structures
	 * members -- an array of addresses, useful for looping over
	 * member -- a mapping of addresses to Member objects
	 * Member -- a struct containing member details
   * tokenSupply -- how many tokens on issue
   * tokens -- mapping of addresses to tokens
	 */
  address[] public members;
  mapping(address => Member) public member;

  struct Member {
        uint joinDate;
        bool exists;
        bool isSpecial;
  }

  uint tokenSupply;
  mapping(address => uint) public tokens;

  	/**
	 * Events: a cheaper option than storing all data on chain
	 * NewMember -- will call when new member joins
	 * Spend -- will call when contract funds spent
   * Transfer -- will call when token is transfered
	 */
  event NewMember(address admin, address newMember, uint joinDate, bool exists, bool isSpecial);
  event Spend(uint date, address recipient, uint amount);
  event Transfer(uint date, address sender, address recipient, uint amount);

	/**
	 * Constructor -- adds msg.sender to membership, sets them as special
	 */
  function Access(){
        member[msg.sender] = Member(now, true, true);
        members.push(msg.sender);
        NewMember(msg.sender, msg.sender, member[msg.sender].joinDate, member[msg.sender].exists, member[msg.sender].isSpecial);
        tokens[msg.sender] += 1000;
        tokenSupply += 1000;
  }

  	/**
	 * Function modifier -- only special members can execute _ block
	 */
  modifier onlySpecial {
      if (member[msg.sender].isSpecial) {
        _
      }
  }

	/// @notice Adds new members or sets existing members to special, onlySpecial can call
	/// @param _nominee the person we are adding as a member
	///	@param _isSpecial if they are special or not
	/// @return success if state changes
  function addMember(address _nominee, bool _isSpecial) onlySpecial returns (bool success){
  		if(!member[_nominee].exists){
            member[_nominee] = Member(now, true, _isSpecial);
            members.push(_nominee);
            tokens[_nominee] += 1000;
            tokenSupply += 1000;
            NewMember(msg.sender, _nominee, member[_nominee].joinDate, member[_nominee].exists, member[_nominee].isSpecial);
            return true;
  		} else if (member[_nominee].exists && _isSpecial){
            member[_nominee].isSpecial = _isSpecial;
            return true;
  		}
        return false;
  }

	/// @notice Spends contract funds, onlySpecial can call
	/// @param _recipient who is recieving the funds
	/// @param _amount how much they are getting
	/// @return success if funds are sent
  function spend(address _recipient, uint _amount) onlySpecial returns (bool success){
  		if(this.balance >= _amount){
            _recipient.send(_amount);
            Spend(now, _recipient, _amount);
            return true;
  		} else {
            return false;
  		}
  }

  /// @notice Gets total supply of issued tokens
  /// @return supply how many tokens are on issue
  function totalSupply() constant returns (uint256 supply){
    return tokenSupply;
  }

  /// @notice Gets the token balance of an address
  /// @param _owner whose address are we looking up
  /// @return balance how many tokens they have
  function balanceOf(address _owner) constant returns (uint256 balance){
    return tokens[_owner];
  }

  /// @notice transfers tokens between users
  /// @param _to who is the transfer to
  /// @param _value how many tokens are they transferring
  /// @return success if the transfer is successful or not
  function transfer(address _to, uint256 _value) returns (bool success){
    if(tokens[msg.sender] >= _value){
      tokens[msg.sender] -= _value;
      tokens[_to] += _value;
      Transfer(now, msg.sender, _to, _value);
      return true;
    }
    return false;
  }
}

/// @author hugooconnor
/// @title A shared account to demo some features of solidity, with standard tokens
/// see how to document solidity code; https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format

contract Access {

	/**
	 * Data structures
	 * members -- an array of addresses, useful for looping over
	 * member -- a mapping of addresses to Member objects
	 * Member -- a struct containing member details
   * tokenSupply -- how many tokens on issue
   * tokens -- mapping of addresses to tokens
	 */
  address[] public members;
  mapping(address => Member) public member;

  struct Member {
        uint joinDate;
        bool exists;
        bool isSpecial;
  }

  uint tokenSupply;
  mapping(address => uint) public tokens;

  	/**
	 * Events: a cheaper option than storing all data on chain
	 * NewMember -- will call when new member joins
	 * Spend -- will call when contract funds spent
	 */
  event NewMember(address admin, address newMember, uint joinDate, bool exists, bool isSpecial);
  event Spend(uint date, address recipient, uint amount);
  event Transfer(uint date, address sender, address recipient, uint amount);

	/**
	 * Constructor -- adds msg.sender to membership, sets them as special
	 */
  function Access(){
        member[msg.sender] = Member(now, true, true);
        members.push(msg.sender);
        NewMember(msg.sender, msg.sender, member[msg.sender].joinDate, member[msg.sender].exists, member[msg.sender].isSpecial);
        tokens[msg.sender] += 1000;
        tokenSupply += 1000;
  }

  	/**
	 * Function modifier -- only special members can execute _ block
	 */
  modifier onlySpecial {
      if (member[msg.sender].isSpecial) {
        _
      }
  }

	/// @notice Adds new members or sets existing members to special, onlySpecial can call
	/// @param _nominee the person we are adding as a member
	///	@param _isSpecial if they are special or not
	/// @return success if state changes
  function addMember(address _nominee, bool _isSpecial) onlySpecial returns (bool success){
  		if(!member[_nominee].exists){
            member[_nominee] = Member(now, true, _isSpecial);
            members.push(_nominee);
            tokens[_nominee] += 1000;
            tokenSupply += 1000;
            NewMember(msg.sender, _nominee, member[_nominee].joinDate, member[_nominee].exists, member[_nominee].isSpecial);
            return true;
  		} else if (member[_nominee].exists && _isSpecial){
            member[_nominee].isSpecial = _isSpecial;
            return true;
  		}
        return false;
  }

	/// @notice Spends contract funds, onlySpecial can call
	/// @param _recipient who is recieving the funds
	/// @param _amount how much they are getting
	/// @return success if funds are sent
  function spend(address _recipient, uint _amount) onlySpecial returns (bool success){
  		if(this.balance >= _amount){
            _recipient.send(_amount);
            Spend(now, _recipient, _amount);
            return true;
  		} else {
            return false;
  		}
  }

  /// @notice Gets total supply of issued tokens
  /// @return supply how many tokens are on issue
  function totalSupply() constant returns (uint256 supply){
    return tokenSupply;
  }

  /// @notice Gets the token balance of an address
  /// @param _owner whose address are we looking up
  /// @return balance how many tokens they have
  function balanceOf(address _owner) constant returns (uint256 balance){
    return tokens[_owner];
  }

  /// @notice transfers tokens between users
  /// @param _to who is the transfer to
  /// @param _value how many tokens are they transferring
  /// @return success if the transfer is successful or not
  function transfer(address _to, uint256 _value) returns (bool success){
    if(tokens[msg.sender] >= _value){
      tokens[msg.sender] -= _value;
      tokens[_to] += _value;
      Transfer(now, msg.sender, _to, _value);
      return true;
    }
    return false;
  }
}