change for loop from members to requirements

import ../user.sol
import ../userMaster.sol

contract GroupRegistry
{
  mapping (address => address[]) groups;
  mapping (address => address) conceptFromGroup;
  address userMasterAddress;

  modifier onlyUser()
  {
    if(userMaster(userMasterAddress).getTokenBalance(msg.sender) <= 0)
    {
      throw;
    }
    _;
  }

  function GroupRegistry(address _userMasterAddress)
  {
    userMasterAddress = _userMasterAddress;
  }

  function addMember(address group) returns (bool success) onlyUser() payable()
  {
    for (uint i = 0, i < Group(group).requirements.length(), i++)
    {
      if(User(msg.sender).getConceptPassed(Group.requirements[i]) == false)
      {
        return false;
      }
      if (Group(group).members.length() = Group(group.size))
      {
        return false;
      }
      Group(group).addMember(msg.sender);
    }
    return true;
  }

  function addGroup(address concept, uint size)
  {
    Group newGroup = new Group(concept, size, msg.sender);
    groups[concept].push(address(Group));
    conceptFromGroup[address(group)] = concept;
  }
}

contract Group
{
  uint public size;
  address[] public members;
  address[] public requirements;
  address concept;
  address registry;

  modifier onlyRegistry()
  {
    if (msg.sender != registry)
    {
      throw;
    }
    _;
  }

  function Group(address _concept, uint _size, address member)
  {
    concept = _concept;
    registry = msg.sender;
    requirements = _size;
    members.push(member);
    size = _size;
  }

  function addMember(address member) onlyRegistry()
  {
    members.push(member);
  }
}

import ../user.sol
import ../userMaster.sol

contract GroupRegistry
{
  mapping (address => address[]) groups;
  mapping (address => address) conceptFromGroup;
  address userMasterAddress;

  modifier onlyUser()
  {
    if(userMaster(userMasterAddress).getTokenBalance(msg.sender) <= 0)
    {
      throw;
    }
    _;
  }

  function GroupRegistry(address _userMasterAddress)
  {
    userMasterAddress = _userMasterAddress;
  }

  function addMember(address group) returns (bool success) onlyUser() payable()
  {
    for (uint i = 0, i < Group(group).members.length(), i++)
    {
      if(User(msg.sender).getConceptPassed(Group.requirements[i]) == false)
      {
        return false;
      }
      if (Group(group).members.length() = Group(group.size))
      {
        return false;
      }
      Group(group).addMember(msg.sender);
    }
    return true;
  }

  function addGroup(address concept, uint size)
  {
    Group newGroup = new Group(concept, size, msg.sender);
    groups[concept].push(address(Group));
    conceptFromGroup[address(group)] = concept;
  }
}

contract Group
{
  uint public size;
  address[] public members;
  address[] public requirements;
  address concept;
  address registry;

  modifier onlyRegistry()
  {
    if (msg.sender != registry)
    {
      throw;
    }
    _;
  }

  function Group(address _concept, uint _size, address member)
  {
    concept = _concept;
    registry = msg.sender;
    requirements = _size;
    members.push(member);
    size = _size;
  }

  function addMember(address member) onlyRegistry()
  {
    members.push(member);
  }
}


Update contracts/dnsregistrar/DNSRegistrar.sol

Co-authored-by: Jeff Lau <0a1b0305cb8dae1a652c441230cf3af3a0eff9e2@hotmail.com>

//SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@ensdomains/buffer/contracts/Buffer.sol";
import "../dnssec-oracle/BytesUtils.sol";
import "../dnssec-oracle/DNSSEC.sol";
import "../dnssec-oracle/RRUtils.sol";
import "../registry/ENSRegistry.sol";
import "../root/Root.sol";
import "../resolvers/profiles/AddrResolver.sol";
import "./DNSClaimChecker.sol";
import "./PublicSuffixList.sol";
import "./IDNSRegistrar.sol";

/**
 * @dev An ENS registrar that allows the owner of a DNS name to claim the
 *      corresponding name in ENS.
 */
// TODO: Record inception time of any claimed name, so old proofs can't be used to revert changes to a name.
contract DNSRegistrar is IDNSRegistrar, IERC165 {
    using BytesUtils for bytes;
    using Buffer for Buffer.buffer;
    using RRUtils for *;

    DNSSEC public oracle;
    ENS public ens;
    PublicSuffixList public suffixes;

    error NoOwnerRecordFound();

    struct OwnerRecord {
        bytes name;
        address owner;
        address resolver;
        uint64 ttl;
    }

    event Claim(bytes32 indexed node, address indexed owner, bytes dnsname);
    event NewOracle(address oracle);
    event NewPublicSuffixList(address suffixes);

    constructor(DNSSEC _dnssec, PublicSuffixList _suffixes, ENS _ens) {
        oracle = _dnssec;
        emit NewOracle(address(oracle));
        suffixes = _suffixes;
        emit NewPublicSuffixList(address(suffixes));
        ens = _ens;
    }

    /**
     * @dev This contract's owner-only functions can be invoked by the owner of the ENS root.
     */
    modifier onlyOwner {
        Root root = Root(ens.owner(bytes32(0)));
        address owner = root.owner();
        require(msg.sender == owner);
        _;
    }

    function setOracle(DNSSEC _dnssec) public onlyOwner {
        oracle = _dnssec;
        emit NewOracle(address(oracle));
    }

    function setPublicSuffixList(PublicSuffixList _suffixes) public onlyOwner {
        suffixes = _suffixes;
        emit NewPublicSuffixList(address(suffixes));
    }

    /**
     * @dev Submits proofs to the DNSSEC oracle, then claims a name using those proofs.
     * @param name The name to claim, in DNS wire format.
     * @param input A chain of signed DNS RRSETs ending with a text record.
     */
    function proveAndClaim(bytes memory name, DNSSEC.RRSetWithSignature[] memory input) public override {
        bytes memory record = oracle.verifyRRSet(input);
        (bytes32 rootNode, bytes32 labelHash, address addr) = _claim(name, record);
        ens.setSubnodeOwner(rootNode, labelHash, addr);
    }

    function proveAndClaimWithResolver(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, address resolver, address addr) public override {
        bytes memory record = oracle.verifyRRSet(input);
        (bytes32 rootNode, bytes32 labelHash, address owner) = _claim(name, record);
        require(msg.sender == owner, "Only owner can call proveAndClaimWithResolver");
        if(addr != address(0)) {
            require(resolver != address(0), "Cannot set addr if resolver is not set");
            // Set ourselves as the owner so we can set a record on the resolver
            ens.setSubnodeRecord(rootNode, labelHash, address(this), resolver, 0);
            bytes32 node = keccak256(abi.encodePacked(rootNode, labelHash));
            // Set the resolver record
            AddrResolver(resolver).setAddr(node, addr);
            // Transfer the record to the owner
            ens.setOwner(node, owner);
        } else {
            ens.setSubnodeRecord(rootNode, labelHash, owner, resolver, 0);
        }
    }

    function supportsInterface(bytes4 interfaceID) external pure override returns (bool) {
        return interfaceID == type(IERC165).interfaceId ||
               interfaceID == type(IDNSRegistrar).interfaceId;
    }

    function _claim(bytes memory name, bytes memory data) internal returns(bytes32 rootNode, bytes32 labelHash, address addr) {
        // Get the first label
        uint labelLen = name.readUint8(0);
        labelHash = name.keccak(1, labelLen);

        // Parent name must be in the public suffix list.
        bytes memory parentName = name.substring(labelLen + 1, name.length - labelLen - 1);
        require(suffixes.isPublicSuffix(parentName), "Parent name must be a public suffix");

        // Make sure the parent name is enabled
        rootNode = enableNode(parentName, 0);

        (addr,) = DNSClaimChecker.getOwnerAddress(name, data);

        emit Claim(keccak256(abi.encodePacked(rootNode, labelHash)), addr, name);
    }

    function enableNode(bytes memory domain, uint offset) internal returns(bytes32 node) {
        uint len = domain.readUint8(offset);
        if(len == 0) {
            return bytes32(0);
        }

        bytes32 parentNode = enableNode(domain, offset + len + 1);
        bytes32 label = domain.keccak(offset + 1, len);
        node = keccak256(abi.encodePacked(parentNode, label));
        address owner = ens.owner(node);
        require(owner == address(0) || owner == address(this), "Cannot enable a name owned by someone else");
        if(owner != address(this)) {
            if(parentNode == bytes32(0)) {
                Root root = Root(ens.owner(bytes32(0)));
                root.setSubnodeOwner(label, address(this));
            } else {
                ens.setSubnodeOwner(parentNode, label, address(this));
            }
        }
        return node;
    }
}

//SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@ensdomains/buffer/contracts/Buffer.sol";
import "../dnssec-oracle/BytesUtils.sol";
import "../dnssec-oracle/DNSSEC.sol";
import "../dnssec-oracle/RRUtils.sol";
import "../registry/ENSRegistry.sol";
import "../root/Root.sol";
import "../resolvers/profiles/AddrResolver.sol";
import "./DNSClaimChecker.sol";
import "./PublicSuffixList.sol";
import "./IDNSRegistrar.sol";

/**
 * @dev An ENS registrar that allows the owner of a DNS name to claim the
 *      corresponding name in ENS.
 */
// TODO: Record inception time of any claimed name, so old proofs can't be used to revert changes to a name.
contract DNSRegistrar is IDNSRegistrar, IERC165 {
    using BytesUtils for bytes;
    using Buffer for Buffer.buffer;
    using RRUtils for *;

    DNSSEC public oracle;
    ENS public ens;
    PublicSuffixList public suffixes;

    error NoOwnerRecordFound();

    struct OwnerRecord {
        bytes name;
        address owner;
        address resolver;
        uint64 ttl;
    }

    event Claim(bytes32 indexed node, address indexed owner, bytes dnsname);
    event NewOracle(address oracle);
    event NewPublicSuffixList(address suffixes);

    constructor(DNSSEC _dnssec, PublicSuffixList _suffixes, ENS _ens) {
        oracle = _dnssec;
        emit NewOracle(address(oracle));
        suffixes = _suffixes;
        emit NewPublicSuffixList(address(suffixes));
        ens = _ens;
    }

    /**
     * @dev This contract's owner-only functions can be invoked by the owner of the ENS root.
     */
    modifier onlyOwner {
        Root root = Root(ens.owner(bytes32(0)));
        address owner = root.owner();
        require(msg.sender == owner);
        _;
    }

    function setOracle(DNSSEC _dnssec) public onlyOwner {
        oracle = _dnssec;
        emit NewOracle(address(oracle));
    }

    function setPublicSuffixList(PublicSuffixList _suffixes) public onlyOwner {
        suffixes = _suffixes;
        emit NewPublicSuffixList(address(suffixes));
    }

    /**
     * @dev Submits proofs to the DNSSEC oracle, then claims a name using those proofs.
     * @param input A chain of signed DNS RRSETs ending with a text record.
     */
    function proveAndClaim(bytes memory name, DNSSEC.RRSetWithSignature[] memory input) public override {
        bytes memory record = oracle.verifyRRSet(input);
        (bytes32 rootNode, bytes32 labelHash, address addr) = _claim(name, record);
        ens.setSubnodeOwner(rootNode, labelHash, addr);
    }

    function proveAndClaimWithResolver(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, address resolver, address addr) public override {
        bytes memory record = oracle.verifyRRSet(input);
        (bytes32 rootNode, bytes32 labelHash, address owner) = _claim(name, record);
        require(msg.sender == owner, "Only owner can call proveAndClaimWithResolver");
        if(addr != address(0)) {
            require(resolver != address(0), "Cannot set addr if resolver is not set");
            // Set ourselves as the owner so we can set a record on the resolver
            ens.setSubnodeRecord(rootNode, labelHash, address(this), resolver, 0);
            bytes32 node = keccak256(abi.encodePacked(rootNode, labelHash));
            // Set the resolver record
            AddrResolver(resolver).setAddr(node, addr);
            // Transfer the record to the owner
            ens.setOwner(node, owner);
        } else {
            ens.setSubnodeRecord(rootNode, labelHash, owner, resolver, 0);
        }
    }

    function supportsInterface(bytes4 interfaceID) external pure override returns (bool) {
        return interfaceID == type(IERC165).interfaceId ||
               interfaceID == type(IDNSRegistrar).interfaceId;
    }

    function _claim(bytes memory name, bytes memory data) internal returns(bytes32 rootNode, bytes32 labelHash, address addr) {
        // Get the first label
        uint labelLen = name.readUint8(0);
        labelHash = name.keccak(1, labelLen);

        // Parent name must be in the public suffix list.
        bytes memory parentName = name.substring(labelLen + 1, name.length - labelLen - 1);
        require(suffixes.isPublicSuffix(parentName), "Parent name must be a public suffix");

        // Make sure the parent name is enabled
        rootNode = enableNode(parentName, 0);

        (addr,) = DNSClaimChecker.getOwnerAddress(name, data);

        emit Claim(keccak256(abi.encodePacked(rootNode, labelHash)), addr, name);
    }

    function enableNode(bytes memory domain, uint offset) internal returns(bytes32 node) {
        uint len = domain.readUint8(offset);
        if(len == 0) {
            return bytes32(0);
        }

        bytes32 parentNode = enableNode(domain, offset + len + 1);
        bytes32 label = domain.keccak(offset + 1, len);
        node = keccak256(abi.encodePacked(parentNode, label));
        address owner = ens.owner(node);
        require(owner == address(0) || owner == address(this), "Cannot enable a name owned by someone else");
        if(owner != address(this)) {
            if(parentNode == bytes32(0)) {
                Root root = Root(ens.owner(bytes32(0)));
                root.setSubnodeOwner(label, address(this));
            } else {
                ens.setSubnodeOwner(parentNode, label, address(this));
            }
        }
        return node;
    }
}


Corrected validateMove() for Rook, Bishop

would not check directions before for Rook and Bishop

/**
 * Chess contract
 * Stores any amount of games with two players and current state.
 * State encoding:
 *    positive numbers for white, negative numbers for black
 *    for details, see
 *    https://github.com/ise-ethereum/on-chain-chess/wiki/Chess-board-representation
 */

 contract Chess {
    bytes constant defaultState = '\x04\x06\x05\x03\x02\x05\x06\x04\x08\x08\x08\x0c\x08\x08\x08\x08\x07\x07\x07\x07\x07\x07\x07\x07\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x09\x09\x09\x09\x09\x09\x09\x09\x08\x08\x08\x08\x08\x08\x08\x08\x0c\x0a\x0b\x0d\x0e\x0b\x0a\x0c\x08\x08\x08\x7c\x08\x08\x08\x08';

    struct Game {
        address player1;
        address player2;
        string player1Alias;
        string player2Alias;
        address nextPlayer;
        address playerWhite; // Player that is white in this game
        address winner;
        int8[128] state;
    }

    mapping (bytes32 => Game) public games;
    mapping (address => mapping (int => bytes32)) public gamesOfPlayers;
    mapping (address => int) public numberGamesOfPlayers;

    // stack of open game ids
    mapping (bytes32 => bytes32) public openGameIds;
    bytes32 public head;

    /* Flags needed for validation
     * Usage e.g. Flags(Flag.FLAG_NAME)
     * Directions(Direction.UP)
     */
    enum Player { WHITE, BLACK }
    enum Direction { UP, UP_RIGHT, RIGHT, DOWN_RIGHT, DOWN, DOWN_LEFT, LEFT, UP_LEFT }
    bytes constant c_Directions = "\x30\x31\x41\x51\x50\x4f\x3f\x2f";
    enum Piece { BLACK_KING, BLACK_QUEEN, BLACK_ROOK, BLACK_BISHOP, BLACK_KNIGHT, BLACK_PAWN, EMPTY, WHITE_PAWN, WHITE_KNIGHT, WHITE_BISHOP, WHITE_ROOK, WHITE_QUEEN, WHITE_KING }
    enum Flag { WHITE_KING_POS, BLACK_KING_POS, CURRENT_PLAYER, WHITE_LEFT_CASTLING, WHITE_RIGHT_CASTLING, BLACK_LEFT_CASTLING, BLACK_RIGHT_CASTLING, BLACK_EN_PASSANT, WHITE_EN_PASSANT}
    bytes constant c_Flags = "\x7b\x0b\x38\x4e\x4f\x3e\x3f\x3d\x4d\x3c\x4c";
    function Flags(Flag i) internal returns (uint) {
       return uint(c_Flags[uint(i)]);
    }
    function Pieces(Piece i) internal returns (int8) {
        return -6 + int8(uint(i));
    }
    function Directions(Direction i) internal returns (int8) {
        return -64 + int8(c_Directions[uint(i)]);
    }
    function Players(Player p) internal returns (int8) {
        if (p == Player.WHITE) {
            return 1;
        }
        return -1;
    }

    bytes constant knightMoves = '\x1f\x21\x2e\x32\x4e\x52\x5f\x61';

    function Chess() {
        head = 'end';
    }

    event GameInitialized(bytes32 indexed gameId, address indexed player1, string player1Alias, address playerWhite);
    event GameJoined(bytes32 indexed gameId, address indexed player1, string player1Alias, address indexed player2, string player2Alias, address playerWhite);
    event GameStateChanged(bytes32 indexed gameId, int8[128] state);
    event Move(bytes32 indexed gameId, address indexed player, uint256 fromIndex, uint256 toIndex);
    event GameEnded(bytes32 indexed gameId, address indexed winner);

    /**
     * Convenience function to set a flag
     * Usage: setFlag(gameId, Flag.BLACK_KING_POS, 4);
     */
    function setFlag(bytes32 gameId, Flag flag, int value) internal {
        games[gameId].state[Flags(flag)] = int8(value);
    }

    /**
     * Convenience function to set a flag
     * Usage: getFlag(gameId, Flag.BLACK_KING_POS);
     */
    function getFlag(bytes32 gameId, Flag flag) internal returns (int8) {
        return games[gameId].state[Flags(flag)];
    }

    /**
     * Initialize a new game
     * string player1Alias: Alias of the player creating the game
     * bool playAsWhite: Pass true or false depending on if the creator will play as white
     */
    function initGame(string player1Alias, bool playAsWhite) public {
        // Generate game id based on player's addresses and current block number
        bytes32 gameId = sha3(msg.sender, block.number);

        // Initialize participants
        games[gameId].player1 = msg.sender;
        games[gameId].player1Alias = player1Alias;

        // Initialize state
        for (uint i = 0; i < 128; i++) {
            // Read defaultState bytes string, which is offset by 8 to be > 0
            games[gameId].state[i] = int8(defaultState[i]) - 8;
        }

        if (playAsWhite) {
            // Player 1 will play as white
            games[gameId].playerWhite = msg.sender;

            // Game starts with White, so here player 1
            games[gameId].nextPlayer = games[gameId].player1;
        }

        // Add game to gamesOfPlayers
        gamesOfPlayers[msg.sender][numberGamesOfPlayers[msg.sender]] = gameId;
        numberGamesOfPlayers[msg.sender]++;

        // Add to openGameIds
        openGameIds[gameId] = head;
        head = gameId;

        // Sent notification events
        GameInitialized(gameId, games[gameId].player1, player1Alias, games[gameId].playerWhite);
        GameStateChanged(gameId, games[gameId].state);
    }

    /**
     * Join an initialized game
     * bytes32 gameId: ID of the game to join
     * string player2Alias: Alias of the player that is joining
     */
    function joinGame(bytes32 gameId, string player2Alias) public {
        // Check that this game does not have a second player yet
        if (games[gameId].player2 != 0) {
            throw;
        }

        games[gameId].player2 = msg.sender;
        games[gameId].player2Alias = player2Alias;

        // If the other player isn't white, player2 will play as white
        if (games[gameId].playerWhite == 0) {
            games[gameId].playerWhite = msg.sender;
            // Game starts with White, so here player2
            games[gameId].nextPlayer = games[gameId].player2;
        }

        // Add game to gamesOfPlayers
        gamesOfPlayers[msg.sender][numberGamesOfPlayers[msg.sender]] = gameId;
        numberGamesOfPlayers[msg.sender]++;

        // Remove from openGameIds
        if (head == gameId) {
            head = openGameIds[head];
            openGameIds[gameId] = 0;
        } else {
            for (var g = head; g != 'end' && openGameIds[g] != 'end'; g = openGameIds[g]) {
                if (openGameIds[g] == gameId) {
                    openGameIds[g] = openGameIds[gameId];
                    openGameIds[gameId] = 0;
                    break;
                }
            }
        }

        GameJoined(gameId, games[gameId].player1, games[gameId].player1Alias, games[gameId].player2, player2Alias, games[gameId].playerWhite);
    }

    /* validates a move and executes it */
    function move(bytes32 gameId, uint256 fromIndex, uint256 toIndex) public {
        // Check that it is this player's turn
        if (games[gameId].nextPlayer != msg.sender) {
            throw;
        }

        int8 currentPlayerColor;
        if (msg.sender == games[gameId].playerWhite) {
            currentPlayerColor = Players(Player.WHITE);
        } else {
            currentPlayerColor = Players(Player.BLACK);
        }

        int8 fromFigure = games[gameId].state[fromIndex];
        int8 toFigure = games[gameId].state[toIndex];

        // Simple sanity checks
        sanityCheck(fromIndex, toIndex, fromFigure, toFigure, currentPlayerColor);

        // Check if move is technically possible
        validateMove(gameId, fromIndex, toIndex, fromFigure, toFigure, currentPlayerColor);

        // For all pieces except knight, check if way is free
        // In case of king, it will check that he is not in check on any of the fields
        if (abs(fromFigure) != uint(Pieces(Piece.BLACK_KNIGHT))) {
            bool checkForCheck = abs(fromFigure) == uint(Pieces(Piece.BLACK_KING));
            checkWayFree(gameId, fromIndex, toIndex, currentPlayerColor, checkForCheck);
        }

        //makeTemporaryMove
        makeTemporaryMove(gameId, fromIndex, toIndex, fromFigure, toFigure);

        //isLegal

        //testIfCheck

        // Update state
        games[gameId].state[toIndex] = games[gameId].state[fromIndex];
        games[gameId].state[fromIndex] = 0;

        // Set nextPlayer
        if (msg.sender == games[gameId].player1) {
            games[gameId].nextPlayer = games[gameId].player2;
        } else {
            games[gameId].nextPlayer = games[gameId].player1;
        }

        Move(gameId, msg.sender, fromIndex, toIndex);
        GameStateChanged(gameId, games[gameId].state);
    }

    function sanityCheck(uint256 fromIndex, uint256 toIndex, int8 fromFigure, int8 toFigure, int8 currentPlayerColor) {
        // check if the move actually fits the data structure
        if (((toIndex & 0x88) != 0) && ((fromIndex & 0x88) != 0)) {
            throw;
        }

        // check if the move tries to move a figure onto it self
        if (fromIndex == toIndex) {
            throw;
        }

        // check if the toIndex is empty (= is 0) or contains an enemy figure ("positive" * "negative" = "negative")
        // --> this only allows captures (negative results)  or moves to empty fields ( = 0)
        // also check if there is a figure at fromIndex to move (fromFigure != 0)
        if (fromFigure * toFigure > 0) {
            throw;
        }

        // check if mover of the figure is the owner of the figure
        // todo: fix color to enum
        if (currentPlayerColor * fromFigure > 0) {
            throw;
        }
    }

    /**
     * Validates if a move is technically (not legally) possible,
     * i.e. if piece is capable to move this way
     */
    function validateMove(bytes32 gameId, uint256 fromIndex, uint256 toIndex, int8 fromFigure, int8 toFigure, int8 movingPlayerColor) {
        int8 direction = getDirection(fromIndex, toIndex);
        bool isDiagonal = !(abs(direction) == 16 || abs(direction) == 1);

        // Kings
        if (abs(fromFigure) == uint(Pieces(Piece.BLACK_KING))) {
            // Normal move
            if (int(fromIndex) + direction == int(toIndex)) {
                return;
            }
            // Castling
            if (checkForCheck(gameId, fromIndex, movingPlayerColor)) {
                // Cannot move if already in check
                throw;
            }
            if (fromFigure == Pieces(Piece.BLACK_KING)) {
                if (4 == fromIndex && toFigure == 0) {
                    if (toIndex == 2 && getFlag(gameId, Flag.BLACK_LEFT_CASTLING) >= 0) {
                        return;
                    }
                    if (toIndex == 6 && getFlag(gameId, Flag.BLACK_RIGHT_CASTLING) >= 0) {
                        return;
                    }
                }
            }
            if (fromFigure == Pieces(Piece.WHITE_KING)) {
                if (116 == fromIndex && toFigure == 0) {
                    if (toIndex == 114 && getFlag(gameId, Flag.WHITE_LEFT_CASTLING) >= 0) {
                        return;
                    }
                    if (toIndex == 118 && getFlag(gameId, Flag.WHITE_RIGHT_CASTLING) >= 0) {
                        return;
                    }
                }
            }

            throw;
        }

        // Bishops, Queens, Rooks
        if (abs(fromFigure) == uint(Pieces(Piece.BLACK_BISHOP)) ||
            abs(fromFigure) == uint(Pieces(Piece.BLACK_QUEEN)) ||
            abs(fromFigure) == uint(Pieces(Piece.BLACK_ROOK))) {

            // Bishop can only walk diagonally, Rook only non-diagonally
            if (!isDiagonal && abs(fromFigure) == uint(Pieces(Piece.BLACK_BISHOP)) ||
                isDiagonal && abs(fromFigure) == uint(Pieces(Piece.BLACK_ROOK))) {
                throw;
            }

            // Traverse all fields in direction
            int temp = int(fromIndex);
            // walk in direction while inside board to find toIndex
            while (temp & 0x88 != 0) {
                if (uint(temp) == toIndex) {
                    return;
                }
                temp += direction;
            }

            throw;
        }

        // Pawns
        if (abs(fromFigure) == uint(Pieces(Piece.BLACK_PAWN))) {
            // Black can only move in positive, White negative direction
            if (fromFigure == Pieces(Piece.BLACK_PAWN) && direction < 0 ||
                fromFigure == Pieces(Piece.WHITE_PAWN) && direction > 0) {
                throw;
            }
            // Forward move
            if (!isDiagonal) {
                if (abs(direction) < 2) {
                    throw;
                }
                // simple move
                if (int(fromIndex) + direction == int(toIndex)) {
                    return;
                }
                // double move
                if (int(fromIndex) + direction + direction == int(toIndex)) {
                    // Can only do double move starting form specific ranks
                    int rank = int(fromIndex/16);
                    if (1 == rank || 6 == rank) {
                        return;
                    }
                }
                throw;
            }
            // diagonal move
            if (int(fromIndex) + direction == int(toIndex)) {
                // if empty, the en passant flag needs to be set
                if (toFigure * fromFigure == 0) {
                    if (fromFigure == Pieces(Piece.BLACK_PAWN) &&
                        getFlag(gameId, Flag.WHITE_EN_PASSANT) == int(toIndex) ||
                        fromFigure == Pieces(Piece.WHITE_PAWN) &&
                        getFlag(gameId, Flag.BLACK_EN_PASSANT) == int(toIndex)) {
                        return;
                    }
                }
                // If not empty
                return;
            }

            throw;
        }

        // Knights
        if (abs(fromFigure) == uint(Pieces(Piece.BLACK_KNIGHT))) {
            for (uint i; i < 8; i++) {
                if (int(fromIndex) + int(knightMoves[i]) - 64 == int(toIndex)) {
                    return;
                }
            }
            throw;
        }

        throw;
    }

    /**
     * Checks if the way between fromIndex and toIndex is unblocked
     */
    function checkWayFree(bytes32 gameId, uint256 fromIndex, uint256 toIndex, int8 currentPlayerColor, bool shouldCheckForCheck) {
        int8 direction = getDirection(fromIndex, toIndex);
        int currentIndex = int(fromIndex) + direction;

        // as long as we do not reach the desired position
        while (int(toIndex) != currentIndex) {
            // we reached the end of the field
            if (currentIndex & 0x88 != 0) {
                throw;
            }
            // the path is blocked
            if (games[gameId].state[uint(currentIndex)] != 0) {
                throw;
            }
            // Check for check in case of kind
            if (shouldCheckForCheck && checkForCheck(gameId, uint(currentIndex), currentPlayerColor)) {
                throw;
            }
            currentIndex = currentIndex + direction;
        }
        return;
    }

    function checkForCheck(bytes32 gameId, uint256 kingAtIndex, int8 currentPlayerColor) returns (bool) {
        // TODO
        return true;
    }

    function getDirection(uint256 fromIndex, uint256 toIndex) returns (int8) {
        // check if the figure is moved up or left of its origin
        bool isAboveLeft = fromIndex > toIndex;

        // check if the figure is moved in an horizontal plane
        // this code works because there is an eight square difference between the horizontal panes (the offboard)
        bool isSameHorizontal = (abs(int256(fromIndex) - int256(toIndex)) < (8));

        // check if the figure is moved in a vertical line
        bool isSameVertical = (fromIndex%8 == toIndex%8);

        // check if the figure is moved to the left of its origin
        bool isLeftSide = (fromIndex%8 > toIndex%8);

        /*Check directions*/
        if (isAboveLeft){
            if (isSameVertical){
                return Directions(Direction.UP);
            }
            if (isSameHorizontal){
                return Directions(Direction.LEFT);
            }
            if (isLeftSide){
                return Directions(Direction.UP_LEFT);
            } else {
                return Directions(Direction.UP_RIGHT);
            }
        } else {
            if (isSameVertical){
                return Directions(Direction.DOWN);
            }
            if (isSameHorizontal){
                return Directions(Direction.RIGHT);
            }
            if (isLeftSide){
                return Directions(Direction.DOWN_LEFT);
            } else{
                return Directions(Direction.DOWN_RIGHT);
            }
        }
    }

    function makeTemporaryMove(bytes32 gameId, uint256 fromIndex, uint256 toIndex, int8 fromFigure, int8 toFigure){
        setFlag(gameId, Flag.WHITE_EN_PASSANT, -1);
        setFlag(gameId, Flag.WHITE_EN_PASSANT, -1);

        // <---- Special Moves ---->

        // castling
        // it already passed valid we just need to move the rook

        // Black
        if (fromFigure == Pieces(Piece.BLACK_KING)){
            setFlag(gameId, Flag.BLACK_KING_POS, int8(toIndex));
            if ((fromIndex == 4)&&(toIndex == 1)){
                games[gameId].state[0] = 0;
                games[gameId].state[2] = Pieces(Piece.BLACK_ROOK);
            }
            if ((fromIndex == 4)&&(toIndex == 6)){
                games[gameId].state[7] = 0;
                games[gameId].state[5] = Pieces(Piece.BLACK_ROOK);
            }

        }
        // White
        if (fromFigure == Pieces(Piece.WHITE_KING)){
            setFlag(gameId, Flag.WHITE_KING_POS, int8(toIndex));
            if ((fromIndex == 116)&&(toIndex == 112)){
                games[gameId].state[112] = 0;
                games[gameId].state[114] = Pieces(Piece.BLACK_ROOK);
            }
            if ((fromIndex == 116)&&(toIndex == 118)){
                games[gameId].state[118] = 0;
                games[gameId].state[117] = Pieces(Piece.BLACK_ROOK);
            }

        }

        //Remove Castling Flag

        // Black
        if (fromFigure == Pieces(Piece.BLACK_KING)){
            if (fromIndex == 4){
                setFlag(gameId, Flag.BLACK_LEFT_CASTLING, -1);
                setFlag(gameId, Flag.BLACK_RIGHT_CASTLING, -1);
            }
        }
        if (fromFigure == Pieces(Piece.BLACK_ROOK)){
            if (fromIndex == 0){
                setFlag(gameId, Flag.BLACK_LEFT_CASTLING, -1);
            }
            if (fromIndex == 7){
                setFlag(gameId, Flag.BLACK_RIGHT_CASTLING, -1);
            }
        }

        // White
        if (fromFigure == Pieces(Piece.WHITE_KING)){
            if (fromIndex == 116){
                setFlag(gameId, Flag.WHITE_LEFT_CASTLING, -1);
                setFlag(gameId, Flag.WHITE_RIGHT_CASTLING, -1);
            }
        }
        if (fromFigure == Pieces(Piece.WHITE_ROOK)){
            if (fromIndex == 112){
                setFlag(gameId, Flag.WHITE_LEFT_CASTLING, -1);
            }
            if (fromIndex == 119){
                setFlag(gameId, Flag.WHITE_RIGHT_CASTLING, -1);
            }
        }
        // En Passant

        // Double Step

        // <---- Normal Moves --->

        games[gameId].state[toIndex] = games[gameId].state[fromIndex];
        games[gameId].state[fromIndex] = 0;

    }

    function isLegal() {

    }

    function testIfCheck() {

    }

    function surrender(bytes32 gameId) public {
        if (games[gameId].winner != 0) {
            // Game already ended
            throw;
        }
        if (games[gameId].player1 == msg.sender) {
            // Player 1 surrendered, player 2 won
            games[gameId].winner = games[gameId].player2;
        } else if(games[gameId].player2 == msg.sender) {
            // Player 2 surrendered, player 1 won
            games[gameId].winner = games[gameId].player1;
        } else {
            // Sender is not a participant of this game
            throw;
        }

        GameEnded(gameId, games[gameId].winner);
    }

    function getGameId(address player, int index) constant returns (bytes32) {
        return gamesOfPlayers[player][index];
    }

    /*------------------------HELPER FUNCTIONS------------------------*/

    // This returns the absolute value of an integer
    function abs(int256 value) returns (uint256){
        if (value>=0) return uint256(value);
        else return uint256(-1*value);
    }

    function is_diagonal(Direction dir) internal returns (bool){
      if(abs(Directions(dir)) == 16)
        return false;
      if(abs(Directions(dir)) == 1)
        return false;
      return true;
    }

    /* This unnamed function is called whenever someone tries to send ether to it */
    function () {
        throw;     // Prevents accidental sending of ether
    }
}

/**
 * Chess contract
 * Stores any amount of games with two players and current state.
 * State encoding:
 *    positive numbers for white, negative numbers for black
 *    for details, see
 *    https://github.com/ise-ethereum/on-chain-chess/wiki/Chess-board-representation
 */

 contract Chess {
    bytes constant defaultState = '\x04\x06\x05\x03\x02\x05\x06\x04\x08\x08\x08\x0c\x08\x08\x08\x08\x07\x07\x07\x07\x07\x07\x07\x07\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x09\x09\x09\x09\x09\x09\x09\x09\x08\x08\x08\x08\x08\x08\x08\x08\x0c\x0a\x0b\x0d\x0e\x0b\x0a\x0c\x08\x08\x08\x7c\x08\x08\x08\x08';

    struct Game {
        address player1;
        address player2;
        string player1Alias;
        string player2Alias;
        address nextPlayer;
        address playerWhite; // Player that is white in this game
        address winner;
        int8[128] state;
    }

    mapping (bytes32 => Game) public games;
    mapping (address => mapping (int => bytes32)) public gamesOfPlayers;
    mapping (address => int) public numberGamesOfPlayers;

    // stack of open game ids
    mapping (bytes32 => bytes32) public openGameIds;
    bytes32 public head;

    /* Flags needed for validation
     * Usage e.g. Flags(Flag.FLAG_NAME)
     * Directions(Direction.UP)
     */
    enum Player { WHITE, BLACK }
    enum Direction { UP, UP_RIGHT, RIGHT, DOWN_RIGHT, DOWN, DOWN_LEFT, LEFT, UP_LEFT }
    bytes constant c_Directions = "\x30\x31\x41\x51\x50\x4f\x3f\x2f";
    enum Piece { BLACK_KING, BLACK_QUEEN, BLACK_ROOK, BLACK_BISHOP, BLACK_KNIGHT, BLACK_PAWN, EMPTY, WHITE_PAWN, WHITE_KNIGHT, WHITE_BISHOP, WHITE_ROOK, WHITE_QUEEN, WHITE_KING }
    enum Flag { WHITE_KING_POS, BLACK_KING_POS, CURRENT_PLAYER, WHITE_LEFT_CASTLING, WHITE_RIGHT_CASTLING, BLACK_LEFT_CASTLING, BLACK_RIGHT_CASTLING, BLACK_EN_PASSANT, WHITE_EN_PASSANT}
    bytes constant c_Flags = "\x7b\x0b\x38\x4e\x4f\x3e\x3f\x3d\x4d\x3c\x4c";
    function Flags(Flag i) internal returns (uint) {
       return uint(c_Flags[uint(i)]);
    }
    function Pieces(Piece i) internal returns (int8) {
        return -6 + int8(uint(i));
    }
    function Directions(Direction i) internal returns (int8) {
        return -64 + int8(c_Directions[uint(i)]);
    }
    function Players(Player p) internal returns (int8) {
        if (p == Player.WHITE) {
            return 1;
        }
        return -1;
    }

    bytes constant knightMoves = '\x1f\x21\x2e\x32\x4e\x52\x5f\x61';

    function Chess() {
        head = 'end';
    }

    event GameInitialized(bytes32 indexed gameId, address indexed player1, string player1Alias, address playerWhite);
    event GameJoined(bytes32 indexed gameId, address indexed player1, string player1Alias, address indexed player2, string player2Alias, address playerWhite);
    event GameStateChanged(bytes32 indexed gameId, int8[128] state);
    event Move(bytes32 indexed gameId, address indexed player, uint256 fromIndex, uint256 toIndex);
    event GameEnded(bytes32 indexed gameId, address indexed winner);

    /**
     * Convenience function to set a flag
     * Usage: setFlag(gameId, Flag.BLACK_KING_POS, 4);
     */
    function setFlag(bytes32 gameId, Flag flag, int value) internal {
        games[gameId].state[Flags(flag)] = int8(value);
    }

    /**
     * Convenience function to set a flag
     * Usage: getFlag(gameId, Flag.BLACK_KING_POS);
     */
    function getFlag(bytes32 gameId, Flag flag) internal returns (int8) {
        return games[gameId].state[Flags(flag)];
    }

    /**
     * Initialize a new game
     * string player1Alias: Alias of the player creating the game
     * bool playAsWhite: Pass true or false depending on if the creator will play as white
     */
    function initGame(string player1Alias, bool playAsWhite) public {
        // Generate game id based on player's addresses and current block number
        bytes32 gameId = sha3(msg.sender, block.number);

        // Initialize participants
        games[gameId].player1 = msg.sender;
        games[gameId].player1Alias = player1Alias;

        // Initialize state
        for (uint i = 0; i < 128; i++) {
            // Read defaultState bytes string, which is offset by 8 to be > 0
            games[gameId].state[i] = int8(defaultState[i]) - 8;
        }

        if (playAsWhite) {
            // Player 1 will play as white
            games[gameId].playerWhite = msg.sender;

            // Game starts with White, so here player 1
            games[gameId].nextPlayer = games[gameId].player1;
        }

        // Add game to gamesOfPlayers
        gamesOfPlayers[msg.sender][numberGamesOfPlayers[msg.sender]] = gameId;
        numberGamesOfPlayers[msg.sender]++;

        // Add to openGameIds
        openGameIds[gameId] = head;
        head = gameId;

        // Sent notification events
        GameInitialized(gameId, games[gameId].player1, player1Alias, games[gameId].playerWhite);
        GameStateChanged(gameId, games[gameId].state);
    }

    /**
     * Join an initialized game
     * bytes32 gameId: ID of the game to join
     * string player2Alias: Alias of the player that is joining
     */
    function joinGame(bytes32 gameId, string player2Alias) public {
        // Check that this game does not have a second player yet
        if (games[gameId].player2 != 0) {
            throw;
        }

        games[gameId].player2 = msg.sender;
        games[gameId].player2Alias = player2Alias;

        // If the other player isn't white, player2 will play as white
        if (games[gameId].playerWhite == 0) {
            games[gameId].playerWhite = msg.sender;
            // Game starts with White, so here player2
            games[gameId].nextPlayer = games[gameId].player2;
        }

        // Add game to gamesOfPlayers
        gamesOfPlayers[msg.sender][numberGamesOfPlayers[msg.sender]] = gameId;
        numberGamesOfPlayers[msg.sender]++;

        // Remove from openGameIds
        if (head == gameId) {
            head = openGameIds[head];
            openGameIds[gameId] = 0;
        } else {
            for (var g = head; g != 'end' && openGameIds[g] != 'end'; g = openGameIds[g]) {
                if (openGameIds[g] == gameId) {
                    openGameIds[g] = openGameIds[gameId];
                    openGameIds[gameId] = 0;
                    break;
                }
            }
        }

        GameJoined(gameId, games[gameId].player1, games[gameId].player1Alias, games[gameId].player2, player2Alias, games[gameId].playerWhite);
    }

    /* validates a move and executes it */
    function move(bytes32 gameId, uint256 fromIndex, uint256 toIndex) public {
        // Check that it is this player's turn
        if (games[gameId].nextPlayer != msg.sender) {
            throw;
        }

        int8 currentPlayerColor;
        if (msg.sender == games[gameId].playerWhite) {
            currentPlayerColor = Players(Player.WHITE);
        } else {
            currentPlayerColor = Players(Player.BLACK);
        }

        int8 fromFigure = games[gameId].state[fromIndex];
        int8 toFigure = games[gameId].state[toIndex];

        // Simple sanity checks
        sanityCheck(fromIndex, toIndex, fromFigure, toFigure, currentPlayerColor);

        // Check if move is technically possible
        validateMove(gameId, fromIndex, toIndex, fromFigure, toFigure, currentPlayerColor);

        // For all pieces except knight, check if way is free
        // In case of king, it will check that he is not in check on any of the fields
        if (abs(fromFigure) != uint(Pieces(Piece.BLACK_KNIGHT))) {
            bool checkForCheck = abs(fromFigure) == uint(Pieces(Piece.BLACK_KING));
            checkWayFree(gameId, fromIndex, toIndex, currentPlayerColor, checkForCheck);
        }

        //makeTemporaryMove
        makeTemporaryMove(gameId, fromIndex, toIndex, fromFigure, toFigure);

        //isLegal

        //testIfCheck

        // Update state
        games[gameId].state[toIndex] = games[gameId].state[fromIndex];
        games[gameId].state[fromIndex] = 0;

        // Set nextPlayer
        if (msg.sender == games[gameId].player1) {
            games[gameId].nextPlayer = games[gameId].player2;
        } else {
            games[gameId].nextPlayer = games[gameId].player1;
        }

        Move(gameId, msg.sender, fromIndex, toIndex);
        GameStateChanged(gameId, games[gameId].state);
    }

    function sanityCheck(uint256 fromIndex, uint256 toIndex, int8 fromFigure, int8 toFigure, int8 currentPlayerColor) {
        // check if the move actually fits the data structure
        if (((toIndex & 0x88) != 0) && ((fromIndex & 0x88) != 0)) {
            throw;
        }

        // check if the move tries to move a figure onto it self
        if (fromIndex == toIndex) {
            throw;
        }

        // check if the toIndex is empty (= is 0) or contains an enemy figure ("positive" * "negative" = "negative")
        // --> this only allows captures (negative results)  or moves to empty fields ( = 0)
        // also check if there is a figure at fromIndex to move (fromFigure != 0)
        if (fromFigure * toFigure > 0) {
            throw;
        }

        // check if mover of the figure is the owner of the figure
        // todo: fix color to enum
        if (currentPlayerColor * fromFigure > 0) {
            throw;
        }
    }

    /**
     * Validates if a move is technically (not legally) possible,
     * i.e. if piece is capable to move this way
     */
    function validateMove(bytes32 gameId, uint256 fromIndex, uint256 toIndex, int8 fromFigure, int8 toFigure, int8 movingPlayerColor) {
        int8 direction = getDirection(fromIndex, toIndex);
        bool isDiagonal = !(abs(direction) == 16 || abs(direction) == 1);

        // Kings
        if (abs(fromFigure) == uint(Pieces(Piece.BLACK_KING))) {
            // Normal move
            if (int(fromIndex) + direction == int(toIndex)) {
                return;
            }
            // Castling
            if (checkForCheck(gameId, fromIndex, movingPlayerColor)) {
                // Cannot move if already in check
                throw;
            }
            if (fromFigure == Pieces(Piece.BLACK_KING)) {
                if (4 == fromIndex && toFigure == 0) {
                    if (toIndex == 2 && getFlag(gameId, Flag.BLACK_LEFT_CASTLING) >= 0) {
                        return;
                    }
                    if (toIndex == 6 && getFlag(gameId, Flag.BLACK_RIGHT_CASTLING) >= 0) {
                        return;
                    }
                }
            }
            if (fromFigure == Pieces(Piece.WHITE_KING)) {
                if (116 == fromIndex && toFigure == 0) {
                    if (toIndex == 114 && getFlag(gameId, Flag.WHITE_LEFT_CASTLING) >= 0) {
                        return;
                    }
                    if (toIndex == 118 && getFlag(gameId, Flag.WHITE_RIGHT_CASTLING) >= 0) {
                        return;
                    }
                }
            }

            throw;
        }

        // Bishops, Queens, Rooks
        if (abs(fromFigure) == uint(Pieces(Piece.BLACK_BISHOP)) ||
            abs(fromFigure) == uint(Pieces(Piece.BLACK_QUEEN)) ||
            abs(fromFigure) == uint(Pieces(Piece.BLACK_ROOK))) {

            if (isDiagonal && abs(fromFigure) == uint(Pieces(Piece.BLACK_BISHOP)) ||
                !isDiagonal && abs(fromFigure) == uint(Pieces(Piece.BLACK_ROOK))) {
                return;
            }

            // Traverse all fields in direction
            int temp = int(fromIndex);
            while (temp & 0x88 != 0) {
                if (uint(temp) == toIndex) {
                    return;
                }
                temp += direction;
            }

            throw;
        }

        // Pawns
        if (abs(fromFigure) == uint(Pieces(Piece.BLACK_PAWN))) {
            // Black can only move in positive, White negative direction
            if (fromFigure == Pieces(Piece.BLACK_PAWN) && direction < 0 ||
                fromFigure == Pieces(Piece.WHITE_PAWN) && direction > 0) {
                throw;
            }
            // Forward move
            if (!isDiagonal) {
                if (abs(direction) < 2) {
                    throw;
                }
                // simple move
                if (int(fromIndex) + direction == int(toIndex)) {
                    return;
                }
                // double move
                if (int(fromIndex) + direction + direction == int(toIndex)) {
                    // Can only do double move starting form specific ranks
                    int rank = int(fromIndex/16);
                    if (1 == rank || 6 == rank) {
                        return;
                    }
                }
                throw;
            }
            // diagonal move
            if (int(fromIndex) + direction == int(toIndex)) {
                // if empty, the en passant flag needs to be set
                if (toFigure * fromFigure == 0) {
                    if (fromFigure == Pieces(Piece.BLACK_PAWN) &&
                        getFlag(gameId, Flag.WHITE_EN_PASSANT) == int(toIndex) ||
                        fromFigure == Pieces(Piece.WHITE_PAWN) &&
                        getFlag(gameId, Flag.BLACK_EN_PASSANT) == int(toIndex)) {
                        return;
                    }
                }
                // If not empty
                return;
            }

            throw;
        }

        // Knights
        if (abs(fromFigure) == uint(Pieces(Piece.BLACK_KNIGHT))) {
            for (uint i; i < 8; i++) {
                if (int(fromIndex) + int(knightMoves[i]) - 64 == int(toIndex)) {
                    return;
                }
            }
            throw;
        }

        throw;
    }

    /**
     * Checks if the way between fromIndex and toIndex is unblocked
     */
    function checkWayFree(bytes32 gameId, uint256 fromIndex, uint256 toIndex, int8 currentPlayerColor, bool shouldCheckForCheck) {
        int8 direction = getDirection(fromIndex, toIndex);
        int currentIndex = int(fromIndex) + direction;

        // as long as we do not reach the desired position
        while (int(toIndex) != currentIndex) {
            // we reached the end of the field
            if (currentIndex & 0x88 != 0) {
                throw;
            }
            // the path is blocked
            if (games[gameId].state[uint(currentIndex)] != 0) {
                throw;
            }
            // Check for check in case of kind
            if (shouldCheckForCheck && checkForCheck(gameId, uint(currentIndex), currentPlayerColor)) {
                throw;
            }
            currentIndex = currentIndex + direction;
        }
        return;
    }

    function checkForCheck(bytes32 gameId, uint256 kingAtIndex, int8 currentPlayerColor) returns (bool) {
        // TODO
        return true;
    }

    function getDirection(uint256 fromIndex, uint256 toIndex) returns (int8) {
        // check if the figure is moved up or left of its origin
        bool isAboveLeft = fromIndex > toIndex;

        // check if the figure is moved in an horizontal plane
        // this code works because there is an eight square difference between the horizontal panes (the offboard)
        bool isSameHorizontal = (abs(int256(fromIndex) - int256(toIndex)) < (8));

        // check if the figure is moved in a vertical line
        bool isSameVertical = (fromIndex%8 == toIndex%8);

        // check if the figure is moved to the left of its origin
        bool isLeftSide = (fromIndex%8 > toIndex%8);

        /*Check directions*/
        if (isAboveLeft){
            if (isSameVertical){
                return Directions(Direction.UP);
            }
            if (isSameHorizontal){
                return Directions(Direction.LEFT);
            }
            if (isLeftSide){
                return Directions(Direction.UP_LEFT);
            } else {
                return Directions(Direction.UP_RIGHT);
            }
        } else {
            if (isSameVertical){
                return Directions(Direction.DOWN);
            }
            if (isSameHorizontal){
                return Directions(Direction.RIGHT);
            }
            if (isLeftSide){
                return Directions(Direction.DOWN_LEFT);
            } else{
                return Directions(Direction.DOWN_RIGHT);
            }
        }
    }

    function makeTemporaryMove(bytes32 gameId, uint256 fromIndex, uint256 toIndex, int8 fromFigure, int8 toFigure){
        setFlag(gameId, Flag.WHITE_EN_PASSANT, -1);
        setFlag(gameId, Flag.WHITE_EN_PASSANT, -1);

        // <---- Special Moves ---->

        // castling
        // it already passed valid we just need to move the rook

        // Black
        if (fromFigure == Pieces(Piece.BLACK_KING)){
            setFlag(gameId, Flag.BLACK_KING_POS, int8(toIndex));
            if ((fromIndex == 4)&&(toIndex == 1)){
                games[gameId].state[0] = 0;
                games[gameId].state[2] = Pieces(Piece.BLACK_ROOK);
            }
            if ((fromIndex == 4)&&(toIndex == 6)){
                games[gameId].state[7] = 0;
                games[gameId].state[5] = Pieces(Piece.BLACK_ROOK);
            }

        }
        // White
        if (fromFigure == Pieces(Piece.WHITE_KING)){
            setFlag(gameId, Flag.WHITE_KING_POS, int8(toIndex));
            if ((fromIndex == 116)&&(toIndex == 112)){
                games[gameId].state[112] = 0;
                games[gameId].state[114] = Pieces(Piece.BLACK_ROOK);
            }
            if ((fromIndex == 116)&&(toIndex == 118)){
                games[gameId].state[118] = 0;
                games[gameId].state[117] = Pieces(Piece.BLACK_ROOK);
            }

        }

        //Remove Castling Flag

        // Black
        if (fromFigure == Pieces(Piece.BLACK_KING)){
            if (fromIndex == 4){
                setFlag(gameId, Flag.BLACK_LEFT_CASTLING, -1);
                setFlag(gameId, Flag.BLACK_RIGHT_CASTLING, -1);
            }
        }
        if (fromFigure == Pieces(Piece.BLACK_ROOK)){
            if (fromIndex == 0){
                setFlag(gameId, Flag.BLACK_LEFT_CASTLING, -1);
            }
            if (fromIndex == 7){
                setFlag(gameId, Flag.BLACK_RIGHT_CASTLING, -1);
            }
        }

        // White
        if (fromFigure == Pieces(Piece.WHITE_KING)){
            if (fromIndex == 116){
                setFlag(gameId, Flag.WHITE_LEFT_CASTLING, -1);
                setFlag(gameId, Flag.WHITE_RIGHT_CASTLING, -1);
            }
        }
        if (fromFigure == Pieces(Piece.WHITE_ROOK)){
            if (fromIndex == 112){
                setFlag(gameId, Flag.WHITE_LEFT_CASTLING, -1);
            }
            if (fromIndex == 119){
                setFlag(gameId, Flag.WHITE_RIGHT_CASTLING, -1);
            }
        }
        // En Passant

        // Double Step

        // <---- Normal Moves --->

        games[gameId].state[toIndex] = games[gameId].state[fromIndex];
        games[gameId].state[fromIndex] = 0;

    }

    function isLegal() {

    }

    function testIfCheck() {

    }

    function surrender(bytes32 gameId) public {
        if (games[gameId].winner != 0) {
            // Game already ended
            throw;
        }
        if (games[gameId].player1 == msg.sender) {
            // Player 1 surrendered, player 2 won
            games[gameId].winner = games[gameId].player2;
        } else if(games[gameId].player2 == msg.sender) {
            // Player 2 surrendered, player 1 won
            games[gameId].winner = games[gameId].player1;
        } else {
            // Sender is not a participant of this game
            throw;
        }

        GameEnded(gameId, games[gameId].winner);
    }

    function getGameId(address player, int index) constant returns (bytes32) {
        return gamesOfPlayers[player][index];
    }

    /*------------------------HELPER FUNCTIONS------------------------*/

    // This returns the absolute value of an integer
    function abs(int256 value) returns (uint256){
        if (value>=0) return uint256(value);
        else return uint256(-1*value);
    }

    function is_diagonal(Direction dir) internal returns (bool){
      if(abs(Directions(dir)) == 16)
        return false;
      if(abs(Directions(dir)) == 1)
        return false;
      return true;
    }

    /* This unnamed function is called whenever someone tries to send ether to it */
    function () {
        throw;     // Prevents accidental sending of ether
    }
}


Delete unnecessary contract

Delete unnecessary contract

pragma solidity ^0.4.11;

// This contract contains functions used for testing the Registry contract
contract Test {

    /*
     * Constructor
     */
    function Test() {}

    /*
     * Testing functions
     */
    function toHash(string _domain) returns (bytes32){
        return sha3(_domain);
    }
    function toParameterHash(string _parameter, uint _value) returns (bytes32){
        return sha3(_parameter, _value);
    }
    function getCurrentTime() returns (uint){
        return now;
    }

}


Start implementing body.

Start implementing body.

contract Body {
  address location;
  uint hp;
  uint ether;
  uint species;
  address brain;

  function get_location() returns (address _location) {
    _location = location;
  }

  function set_brain(address _brain) {
    brain = _brain;
  }

  function set_ether(address _ether) {
    ether = _ether;
  }

  function set_hp(address _hp) {
    hp = _hp;
  }

  function set_location(address _location) {
    location = _location;
  }

  function set_species(address _species) {
    species = _species;
  }
}

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


reshuffle

reshuffle

contract Token {
  address public owner;
  uint256 public maxTokens;

  mapping (address => uint256) public balances;

  /* public event on the blockchain that will notify clients */
  /*event Transfer(address indexed from, address indexed to, uint256 value);*/

  function Token() {
    owner = msg.sender; // contract owner is contract creator
    maxTokens = 10000000;
  }

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

  function setMaxTokens(uint256 _maxTokens) onlyOwner {
      maxTokens = _maxTokens;
  }

  function issue(address _to, uint256 _value) onlyOwner {
    if (_value <= maxTokens) {
      balances[_to] = _value;
    }
  }

  function setOwner(address _newOwner) onlyOwner {
      owner = _newOwner;
  }

  // user functions -------------------------------
  function transfer(address _to, uint256 _value) {
    if (balances[msg.sender] >= _value) {           // Check if the sender has enough*/
      if (balances[_to] + _value < balances[_to]) throw;  // Check for overflows

      balances[msg.sender] -= _value;                     // Subtract from the sender
      balances[_to] += _value;                            // Add the same to the recipient
    }
    /*Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place*/
  }

  function getBalance(address addr) returns(uint256) {
    return balances[addr];
  }

  /* This unnamed function is called whenever someone tries to transfer ether to it */
  function () {
    throw;     // Prevents accidental sending of ether
  }
}

contract Token {
  address public owner;
  uint256 public maxTokens;

  mapping (address => uint256) public balances;
  /*array addresses;*/

  /* public event on the blockchain that will notify clients */
  /*event Transfer(address indexed from, address indexed to, uint256 value);*/

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

  function Token() {
    owner = msg.sender; // contract owner is contract creator
    maxTokens = 10000000;
  }

  // owner functions ----------------------------
  function setMaxTokens(uint256 _maxTokens) onlyOwner {
      maxTokens = _maxTokens;
  }

  function issue(address _to, uint256 _value) onlyOwner {
    if (_value <= maxTokens) {
      balances[_to] = _value;
    }
  }

  function setOwner(address _newOwner) onlyOwner {
      owner = _newOwner;
  }

  // user functions -------------------------------
  function transfer(address _to, uint256 _value) {
    if (balances[msg.sender] >= _value) {           // Check if the sender has enough*/
      if (balances[_to] + _value < balances[_to]) throw;  // Check for overflows

      balances[msg.sender] -= _value;                     // Subtract from the sender
      balances[_to] += _value;                            // Add the same to the recipient
    }
    /*Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place*/
  }

  function getBalance(address addr) returns(uint256) {
    return balances[addr];
  }

  /* This unnamed function is called whenever someone tries to transfer ether to it */
  function () {
    throw;     // Prevents accidental sending of ether
  }
}


creator as resolver for now

creator as resolver for now

pragma solidity ^0.4.11;

import './bet.sol';

contract ebets {
  address resolver;

  event created_bet(address bet_addr);
  function ebets() {
    resolver = msg.sender;
  }

  function create_bet(string title, string category,
                      string team_0, string team_1, uint timestamp_match_begin,
                      uint timestamp_match_end, uint timestamp_hard_deadline,
                      uint timestamp_terminate_deadline, string url_oraclize) {

    address bet = new Bet(resolver, title, category, team_0, team_1,
                              timestamp_match_begin, timestamp_match_end,
                              timestamp_hard_deadline, timestamp_terminate_deadline,
                              url_oraclize);
    created_bet(bet);
  }
}

pragma solidity ^0.4.11;

import './bet.sol';

contract ebets {
  address resolver;

  event created_bet(address bet_addr);
  function ebets() {
    resolver = msg.sender;
  }

  function create_bet(string title, string category,
                      string team_0, string team_1, uint timestamp_match_begin,
                      uint timestamp_match_end, uint timestamp_hard_deadline,
                      uint timestamp_terminate_deadline, string url_oraclize) {
    address bet = new Bet(this, title, category, team_0, team_1,
                              timestamp_match_begin, timestamp_match_end,
                              timestamp_hard_deadline, timestamp_terminate_deadline,
                              url_oraclize);
    created_bet(bet);
  }
}


Clarify safe conversion uint -> int.

Clarify safe conversion uint -> int.

pragma solidity ^0.4.11;

import 'zeppelin-solidity/contracts/math/SafeMath.sol';
import 'zeppelin-solidity/contracts/math/Math.sol';

/**
 * @title Standing order
 * @dev Lifecycle of a standing order:
 *  - the payment amount per interval is set at construction time and can not be changed afterwards
 *  - the payee is set by the owner and can not be changed after creation
 *  - at <startTime> (unix timestamp) the first payment is due
 *  - every <intervall> seconds the next payment is due
 *  - the owner can add funds to the order contract at any time
 *  - the owner can withdraw only funds that do not (yet) belong to the payee
 *  - the owner can terminate a standingorder anytime. Termination results in:
 *    - No further funding being allowed
 *    - order marked as "terminated" and not being displayed anymore in owner UI
 *    - as long as there are uncollected funds entitled to the payee, it is still displayed in payee UI
 *    - the payee can still collect funds owned to him
 *
 *   * Terminology *
 *   "withdraw" -> performed by owner - transfer funds stored in contract back to owner
 *   "collect"  -> performed by payee - transfer entitled funds from contract to payee
 *
 *   * How does a payment work? *
 *   Since a contract can not trigger a payment by itself, it provides the method "collectFunds" for the payee.
 *   The payee can always query the contract to determine how many funds he is entitled to collect.
 *   The payee can call "collectFunds" to initiate transfer of entitled funds to his address.
 */
contract StandingOrder {

    using SafeMath for uint;
    using Math for uint;

    address public owner;        /** The owner of this order */
    address public payee;        /** The payee is the receiver of funds */
    uint public startTime;       /** Date and time (unix timestamp - seconds since 1970) when first payment can be claimed by payee */
    uint public paymentInterval; /** Interval for payments (Unit: seconds) */
    uint public paymentAmount;   /** How much can payee claim per period (Unit: Wei) */
    uint public claimedFunds;    /** How much funds have been claimed already (Unit: Wei) */
    string public ownerLabel;    /** Label (set by contract owner) */
    bool public isTerminated;    /** Marks order as terminated */
    uint public terminationTime; /** Date and time (unix timestamp - seconds since 1970) when order terminated */

    modifier onlyPayee() {
        require(msg.sender == payee);
        _;
    }

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

    /** Event triggered when payee collects funds */
    event Collect(uint amount);
    /** Event triggered when contract gets funded */
    event Fund(uint amount);
    /** Event triggered when owner withdraws funds */
    event Withdraw(uint amount);

    /**
     * Constructor
     * @param _owner The owner of the contract
     * @param _payee The payee - the account that can collect payments from this contract
     * @param _paymentInterval Interval for payments, unit: seconds
     * @param _paymentAmount The amount payee can claim per period, unit: wei
     * @param _startTime Date and time (unix timestamp - seconds since 1970) when first payment can be claimed by payee
     * @param _label Label for contract, e.g "rent" or "weekly paycheck"
     */
    function StandingOrder(
        address _owner,
        address _payee,
        uint _paymentInterval,
        uint _paymentAmount,
        uint _startTime,
        string _label
    )
        payable
    {
        // Sanity check parameters
        require(_paymentInterval > 0);
        require(_paymentAmount > 0);
        // Following check is not exact for unicode strings, but here i just want to make sure that some label is provided
        // See https://ethereum.stackexchange.com/questions/13862/is-it-possible-to-check-string-variables-length-inside-the-contract/13886
        require(bytes(_label).length > 2);

        // Set owner to _owner, as msg.sender is the StandingOrderFactory contract
        owner = _owner;

        payee = _payee;
        paymentInterval = _paymentInterval;
        paymentAmount = _paymentAmount;
        ownerLabel = _label;
        startTime = _startTime;
        isTerminated = false;
    }

    /**
     * Fallback function.
     * Allows adding funds to existing order. Will throw in case the order is terminated!
     */
    function() payable {
        // TODO: Dont make contract as a whole payable. Instead create a dedicated "addFunds" method to prevent any accidental payment!
        if (isTerminated) {
            // adding funds not allowed for terminated orders
            revert();
        }
        // Log Fund event
        Fund(msg.value);
    }

    /**
     * Determine how much funds payee is entitled to collect
     * Note that this might be more than actual funds available!
     * @return Number of wei that payee is entitled to collect
     */
    function getEntitledFunds() constant returns (uint) {
        // First check if the contract startTime has been reached at all
        if (now < startTime) {
            // startTime not yet reached
            return 0;
        }

        // startTime has been reached, so add first payment
        uint entitledAmount = paymentAmount;

        // Determine endTime for calculation. If order has been terminated -> terminationTime, otherwise current time
        uint endTime = isTerminated ? terminationTime : now;

        // calculate number of complete intervals since startTime
        uint runtime = endTime.sub(startTime);
        uint completeIntervals = runtime.div(paymentInterval); // TODO: still implicitly rounding down?
        // add interval * paymentAmount to entitledAmount
        entitledAmount = entitledAmount.add(completeIntervals.mul(paymentAmount));

        // subtract already collected funds
        return entitledAmount.sub(claimedFunds);
    }

    /**
     * Determine how much funds are available for payee to collect
     * This can be less than the entitled amount if the contract does not have enough funds to cover the due payments,
     * in other words: The owner has not put enough funds into the contract.
     * @return Number of wei that payee can collect
     */
    function getUnclaimedFunds() constant returns (uint) {
        // don't return more than available balance
        return getEntitledFunds().min256(this.balance);
    }

    /**
     * Determine how much funds are still owned by owner (not yet reserved for payee)
     * Note that this can be negative in case contract is not funded enough to cover entitled amount for payee!
     * @return number of wei belonging owner, negative if contract is missing funds to cover payments
     */
    function getOwnerFunds() constant returns (int) {
        // Conversion from unsigned int to int will produce unexpected results only for very large
        // numbers (2^255 and greater). This is about 5.7e+58 ether.
        // -> There will be no situation when the contract balance (this.balance) will hit this limit
        // -> getEntitledFunds() might end up hitting this limit when the contract creator INTENTIONALLY sets
        //    any combination of absurdly high payment rate, low interval or a startTime way in the past.
        //    Being entitled to more than 5.7e+58 ether obviously will never be an expected usecase
        // Therefor the conversion can be considered safe here.
        return int256(this.balance) - int256(getEntitledFunds());
    }

    /**
     * Collect payment
     * Can only be called by payee. This will transfer all available funds (see getUnclaimedFunds) to payee
     * @return amount that has been transferred!
     */
    function collectFunds() onlyPayee returns(uint) {
        uint amount = getUnclaimedFunds();
        if (amount <= 0) {
            // nothing to collect :-(
            revert();
        }

        // keep track of collected funds
        claimedFunds = claimedFunds.add(amount);

        // create log entry
        Collect(amount);

        // initiate transfer of unclaimed funds to payee
        payee.transfer(amount);

        return amount;
    }

    /**
     * Withdraw requested amount back to owner.
     * Only funds not (yet) reserved for payee can be withdrawn. So it is not possible for the owner
     * to withdraw unclaimed funds - They can only be claimed by payee!
     * Withdrawing funds does not terminate the order, at any time owner can fund it again!
     * @param amount Number of wei owner wants to withdraw
     */
    function WithdrawOwnerFunds(uint amount) onlyOwner {
        int intOwnerFunds = getOwnerFunds(); // this might be negative in case of underfunded contract!
        if (intOwnerFunds <= 0) {
            // nothing available to withdraw :-(
            revert();
        }
        // conversion int -> uint is safe here as I'm checking <= 0 above!
        uint256 ownerFunds = uint256(intOwnerFunds);

        if (amount > ownerFunds) {
            // Trying to withdraw more than available!
            revert();
        }

        // Log Withdraw event
        Withdraw(amount);

        owner.transfer(amount);
    }

    /**
     * Terminate order
     * Marks the order as terminated.
     * Can only be executed if no ownerfunds are left
     */
    function Terminate() onlyOwner {
        assert(getOwnerFunds() <= 0);
        terminationTime = now;
        isTerminated = true;
    }
}

/**
 * @title StandingOrder factory
 */
contract StandingOrderFactory {
    // keep track who issued standing orders
    mapping (address => StandingOrder[]) public standingOrdersByOwner;
    // keep track of payees of standing orders
    mapping (address => StandingOrder[]) public standingOrdersByPayee;

    // Events
    event LogOrderCreated(
        address orderAddress,
        address indexed owner,
        address indexed payee
    );

    /**
     * Create a new standing order
     * The owner of the new order will be the address that called this function (msg.sender)
     * @param _payee The payee - the account that can collect payments from this contract
     * @param _paymentInterval Interval for payments, unit: seconds
     * @param _paymentAmount The amount payee can claim per period, unit: wei
     * @param _startTime Date and time (unix timestamp - seconds since 1970) when first payment can be claimed by payee
     * @param _label Label for contract, e.g "rent" or "weekly paycheck"
     * @return Address of new created standingOrder contract
     */
    function createStandingOrder(address _payee, uint _paymentAmount, uint _paymentInterval, uint _startTime, string _label) returns (StandingOrder) {
        StandingOrder so = new StandingOrder(msg.sender, _payee, _paymentInterval, _paymentAmount, _startTime, _label);
        standingOrdersByOwner[msg.sender].push(so);
        standingOrdersByPayee[_payee].push(so);
        LogOrderCreated(so, msg.sender, _payee);
        return so;
    }

    /**
     * Determine how many orders are owned by caller (msg.sender)
     * @return Number of orders
     */
    function getNumOrdersByOwner() constant returns (uint) {
        return standingOrdersByOwner[msg.sender].length;
    }

    /**
     * Get order by index from the Owner mapping
     * @param index Index of order
     * @return standing order address
     */
    function getOwnOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByOwner[msg.sender][index];
    }

    /**
     * Determine how many orders are paying to caller (msg.sender)
     * @return Number of orders
     */
    function getNumOrdersByPayee() constant returns (uint) {
        return standingOrdersByPayee[msg.sender].length;
    }

    /**
     * Get order by index from the Payee mapping
     * @param index Index of order
     * @return standing order address
     */
    function getPaidOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByPayee[msg.sender][index];
    }
}

pragma solidity ^0.4.11;

import 'zeppelin-solidity/contracts/math/SafeMath.sol';
import 'zeppelin-solidity/contracts/math/Math.sol';

/**
 * @title Standing order
 * @dev Lifecycle of a standing order:
 *  - the payment amount per interval is set at construction time and can not be changed afterwards
 *  - the payee is set by the owner and can not be changed after creation
 *  - at <startTime> (unix timestamp) the first payment is due
 *  - every <intervall> seconds the next payment is due
 *  - the owner can add funds to the order contract at any time
 *  - the owner can withdraw only funds that do not (yet) belong to the payee
 *  - the owner can terminate a standingorder anytime. Termination results in:
 *    - No further funding being allowed
 *    - order marked as "terminated" and not being displayed anymore in owner UI
 *    - as long as there are uncollected funds entitled to the payee, it is still displayed in payee UI
 *    - the payee can still collect funds owned to him
 *
 *   * Terminology *
 *   "withdraw" -> performed by owner - transfer funds stored in contract back to owner
 *   "collect"  -> performed by payee - transfer entitled funds from contract to payee
 *
 *   * How does a payment work? *
 *   Since a contract can not trigger a payment by itself, it provides the method "collectFunds" for the payee.
 *   The payee can always query the contract to determine how many funds he is entitled to collect.
 *   The payee can call "collectFunds" to initiate transfer of entitled funds to his address.
 */
contract StandingOrder {

    using SafeMath for uint;
    using Math for uint;

    address public owner;        /** The owner of this order */
    address public payee;        /** The payee is the receiver of funds */
    uint public startTime;       /** Date and time (unix timestamp - seconds since 1970) when first payment can be claimed by payee */
    uint public paymentInterval; /** Interval for payments (Unit: seconds) */
    uint public paymentAmount;   /** How much can payee claim per period (Unit: Wei) */
    uint public claimedFunds;    /** How much funds have been claimed already (Unit: Wei) */
    string public ownerLabel;    /** Label (set by contract owner) */
    bool public isTerminated;    /** Marks order as terminated */
    uint public terminationTime; /** Date and time (unix timestamp - seconds since 1970) when order terminated */

    modifier onlyPayee() {
        require(msg.sender == payee);
        _;
    }

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

    /** Event triggered when payee collects funds */
    event Collect(uint amount);
    /** Event triggered when contract gets funded */
    event Fund(uint amount);
    /** Event triggered when owner withdraws funds */
    event Withdraw(uint amount);

    /**
     * Constructor
     * @param _owner The owner of the contract
     * @param _payee The payee - the account that can collect payments from this contract
     * @param _paymentInterval Interval for payments, unit: seconds
     * @param _paymentAmount The amount payee can claim per period, unit: wei
     * @param _startTime Date and time (unix timestamp - seconds since 1970) when first payment can be claimed by payee
     * @param _label Label for contract, e.g "rent" or "weekly paycheck"
     */
    function StandingOrder(
        address _owner,
        address _payee,
        uint _paymentInterval,
        uint _paymentAmount,
        uint _startTime,
        string _label
    )
        payable
    {
        // Sanity check parameters
        require(_paymentInterval > 0);
        require(_paymentAmount > 0);
        // Following check is not exact for unicode strings, but here i just want to make sure that some label is provided
        // See https://ethereum.stackexchange.com/questions/13862/is-it-possible-to-check-string-variables-length-inside-the-contract/13886
        require(bytes(_label).length > 2);

        // Set owner to _owner, as msg.sender is the StandingOrderFactory contract
        owner = _owner;

        payee = _payee;
        paymentInterval = _paymentInterval;
        paymentAmount = _paymentAmount;
        ownerLabel = _label;
        startTime = _startTime;
        isTerminated = false;
    }

    /**
     * Fallback function.
     * Allows adding funds to existing order. Will throw in case the order is terminated!
     */
    function() payable {
        // TODO: Dont make contract as a whole payable. Instead create a dedicated "addFunds" method to prevent any accidental payment!
        if (isTerminated) {
            // adding funds not allowed for terminated orders
            revert();
        }
        // Log Fund event
        Fund(msg.value);
    }

    /**
     * Determine how much funds payee is entitled to collect
     * Note that this might be more than actual funds available!
     * @return Number of wei that payee is entitled to collect
     */
    function getEntitledFunds() constant returns (uint) {
        // First check if the contract startTime has been reached at all
        if (now < startTime) {
            // startTime not yet reached
            return 0;
        }

        // startTime has been reached, so add first payment
        uint entitledAmount = paymentAmount;

        // Determine endTime for calculation. If order has been terminated -> terminationTime, otherwise current time
        uint endTime = isTerminated ? terminationTime : now;

        // calculate number of complete intervals since startTime
        uint runtime = endTime.sub(startTime);
        uint completeIntervals = runtime.div(paymentInterval); // TODO: still implicitly rounding down?
        // add interval * paymentAmount to entitledAmount
        entitledAmount = entitledAmount.add(completeIntervals.mul(paymentAmount));

        // subtract already collected funds
        return entitledAmount.sub(claimedFunds);
    }

    /**
     * Determine how much funds are available for payee to collect
     * This can be less than the entitled amount if the contract does not have enough funds to cover the due payments,
     * in other words: The owner has not put enough funds into the contract.
     * @return Number of wei that payee can collect
     */
    function getUnclaimedFunds() constant returns (uint) {
        // don't return more than available balance
        return getEntitledFunds().min256(this.balance);
    }

    /**
     * Determine how much funds are still owned by owner (not yet reserved for payee)
     * Note that this can be negative in case contract is not funded enough to cover entitled amount for payee!
     * @return number of wei belonging owner, negative if contract is missing funds to cover payments
     */
    function getOwnerFunds() constant returns (int) {
        // Conversion from unsigned int to int will produce unexpected results only for very large
        // numbers (2^255 and greater)
        // TODO: Make this bulletproof also for large amounts and use safemath!
        return int256(this.balance) - int256(getEntitledFunds());
    }

    /**
     * Collect payment
     * Can only be called by payee. This will transfer all available funds (see getUnclaimedFunds) to payee
     * @return amount that has been transferred!
     */
    function collectFunds() onlyPayee returns(uint) {
        uint amount = getUnclaimedFunds();
        if (amount <= 0) {
            // nothing to collect :-(
            revert();
        }

        // keep track of collected funds
        claimedFunds = claimedFunds.add(amount);

        // create log entry
        Collect(amount);

        // initiate transfer of unclaimed funds to payee
        payee.transfer(amount);

        return amount;
    }

    /**
     * Withdraw requested amount back to owner.
     * Only funds not (yet) reserved for payee can be withdrawn. So it is not possible for the owner
     * to withdraw unclaimed funds - They can only be claimed by payee!
     * Withdrawing funds does not terminate the order, at any time owner can fund it again!
     * @param amount Number of wei owner wants to withdraw
     */
    function WithdrawOwnerFunds(uint amount) onlyOwner {
        int intOwnerFunds = getOwnerFunds(); // this might be negative in case of underfunded contract!
        if (intOwnerFunds <= 0) {
            // nothing available to withdraw :-(
            revert();
        }
        // conversion int -> uint is safe here as I'm checking <= 0 above!
        uint256 ownerFunds = uint256(intOwnerFunds);

        if (amount > ownerFunds) {
            // Trying to withdraw more than available!
            revert();
        }

        // Log Withdraw event
        // TODO: Log event after successfull transfer only?!?
        Withdraw(amount);

        owner.transfer(amount);
    }

    /**
     * Terminate order
     * Marks the order as terminated.
     * Can only be executed if no ownerfunds are left
     */
    function Terminate() onlyOwner {
        assert(getOwnerFunds() <= 0);
        terminationTime = now;
        isTerminated = true;
    }
}

/**
 * @title StandingOrder factory
 */
contract StandingOrderFactory {
    // keep track who issued standing orders
    mapping (address => StandingOrder[]) public standingOrdersByOwner;
    // keep track of payees of standing orders
    mapping (address => StandingOrder[]) public standingOrdersByPayee;

    // Events
    event LogOrderCreated(
        address orderAddress,
        address indexed owner,
        address indexed payee
    );

    /**
     * Create a new standing order
     * The owner of the new order will be the address that called this function (msg.sender)
     * @param _payee The payee - the account that can collect payments from this contract
     * @param _paymentInterval Interval for payments, unit: seconds
     * @param _paymentAmount The amount payee can claim per period, unit: wei
     * @param _startTime Date and time (unix timestamp - seconds since 1970) when first payment can be claimed by payee
     * @param _label Label for contract, e.g "rent" or "weekly paycheck"
     * @return Address of new created standingOrder contract
     */
    function createStandingOrder(address _payee, uint _paymentAmount, uint _paymentInterval, uint _startTime, string _label) returns (StandingOrder) {
        StandingOrder so = new StandingOrder(msg.sender, _payee, _paymentInterval, _paymentAmount, _startTime, _label);
        standingOrdersByOwner[msg.sender].push(so);
        standingOrdersByPayee[_payee].push(so);
        LogOrderCreated(so, msg.sender, _payee);
        return so;
    }

    /**
     * Determine how many orders are owned by caller (msg.sender)
     * @return Number of orders
     */
    function getNumOrdersByOwner() constant returns (uint) {
        return standingOrdersByOwner[msg.sender].length;
    }

    /**
     * Get order by index from the Owner mapping
     * @param index Index of order
     * @return standing order address
     */
    function getOwnOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByOwner[msg.sender][index];
    }

    /**
     * Determine how many orders are paying to caller (msg.sender)
     * @return Number of orders
     */
    function getNumOrdersByPayee() constant returns (uint) {
        return standingOrdersByPayee[msg.sender].length;
    }

    /**
     * Get order by index from the Payee mapping
     * @param index Index of order
     * @return standing order address
     */
    function getPaidOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByPayee[msg.sender][index];
    }
}


Update TokenTimelock.sol: Issue #464

Update TokenTimelock.sol: Issue #464

Removed deprecated function claim() as per Issue #464.

pragma solidity ^0.4.11;

import './ERC20Basic.sol';
import "../token/SafeERC20.sol";

/**
 * @title TokenTimelock
 * @dev TokenTimelock is a token holder contract that will allow a
 * beneficiary to extract the tokens after a given release time
 */
contract TokenTimelock {
  using SafeERC20 for ERC20Basic;

  // ERC20 basic token contract being held
  ERC20Basic public token;

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

  // timestamp when token release is enabled
  uint64 public releaseTime;

  function TokenTimelock(ERC20Basic _token, address _beneficiary, uint64 _releaseTime) {
    require(_releaseTime > now);
    token = _token;
    beneficiary = _beneficiary;
    releaseTime = _releaseTime;
  }

  /**
   * @notice Transfers tokens held by timelock to beneficiary.
   */
  function release() public {
    require(now >= releaseTime);

    uint256 amount = token.balanceOf(this);
    require(amount > 0);

    token.safeTransfer(beneficiary, amount);
  }
}

pragma solidity ^0.4.11;

import './ERC20Basic.sol';
import "../token/SafeERC20.sol";

/**
 * @title TokenTimelock
 * @dev TokenTimelock is a token holder contract that will allow a
 * beneficiary to extract the tokens after a given release time
 */
contract TokenTimelock {
  using SafeERC20 for ERC20Basic;

  // ERC20 basic token contract being held
  ERC20Basic public token;

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

  // timestamp when token release is enabled
  uint64 public releaseTime;

  function TokenTimelock(ERC20Basic _token, address _beneficiary, uint64 _releaseTime) {
    require(_releaseTime > now);
    token = _token;
    beneficiary = _beneficiary;
    releaseTime = _releaseTime;
  }

  /**
   * @notice Transfers tokens held by timelock to beneficiary.
   * Deprecated: please use TokenTimelock#release instead.
   */
  function claim() public {
    require(msg.sender == beneficiary);
    release();
  }

  /**
   * @notice Transfers tokens held by timelock to beneficiary.
   */
  function release() public {
    require(now >= releaseTime);

    uint256 amount = token.balanceOf(this);
    require(amount > 0);

    token.safeTransfer(beneficiary, amount);
  }
}