removed logs from std contracts

removed logs from std contracts

//TODO: use imports
contract owned{function owned(){owner = msg.sender;}modifier onlyowner(){if(msg.sender==owner)_}address owner;}
contract mortal is owned {function kill() { if (msg.sender == owner) suicide(owner); }}

//sol Config
// Simple global configuration registrar.
// @authors:
//   Gav Wood <g@ethdev.com>

contract Config is mortal {
	function register(uint id, address service) {
		if (tx.origin != owner)
			return;
		services[id] = service;
	}

	function unregister(uint id) {
		if (msg.sender != owner && services[id] != msg.sender)
			return;
		services[id] = address(0);
	}

	function lookup(uint service) constant returns(address a) {
		return services[service];
	}

	mapping (uint => address) services;
}

/*

// Solidity Interface:
contract Config{function lookup(uint256 service)constant returns(address a){}function kill(){}function unregister(uint256 id){}function register(uint256 id,address service){}}

// Example Solidity use:
address addrConfig = 0xf025d81196b72fba60a1d4dddad12eeb8360d828;
address addrNameReg = Config(addrConfig).lookup(1);

// JS Interface:
var abiConfig = [{"constant":false,"inputs":[],"name":"kill","outputs":[]},{"constant":true,"inputs":[{"name":"service","type":"uint256"}],"name":"lookup","outputs":[{"name":"a","type":"address"}]},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"service","type":"address"}],"name":"register","outputs":[]},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"unregister","outputs":[]}];

// Example JS use:
var addrConfig = "0x661005d2720d855f1d9976f88bb10c1a3398c77f";
var addrNameReg;
web3.eth.contract(addrConfig, abiConfig).lookup(1).call().then(function(r){ addrNameReg = r; })

*/

//sol NameReg
// Simple global name registrar.
// @authors:
//   kobigurk (from #ethereum-dev)
//   Gav Wood <g@ethdev.com>

contract NameRegister {
	function getAddress(bytes32 _name) constant returns (address o_owner) {}
	function getName(address _owner) constant returns (bytes32 o_name) {}
}

contract NameReg is owned, NameRegister {
	function NameReg() {
		address addrConfig = 0xf025d81196b72fba60a1d4dddad12eeb8360d828;
		toName[addrConfig] = "Config";
		toAddress["Config"] = addrConfig;
		toName[this] = "NameReg";
		toAddress["NameReg"] = this;
		Config(addrConfig).register(1, this);
	}

	function register(bytes32 name) {
		// Don't allow the same name to be overwritten.
		if (toAddress[name] != address(0))
			return;
		// Unregister previous name if there was one.
		if (toName[msg.sender] != "")
			toAddress[toName[msg.sender]] = 0;

		toName[msg.sender] = name;
		toAddress[name] = msg.sender;
	}

	function unregister() {
		bytes32 n = toName[msg.sender];
		if (n == "")
			return;
		toName[msg.sender] = "";
		toAddress[n] = address(0);
	}

	function addressOf(bytes32 name) constant returns (address addr) {
		return toAddress[name];
	}

	function nameOf(address addr) constant returns (bytes32 name) {
		return toName[addr];
	}

	mapping (address => bytes32) toName;
	mapping (bytes32 => address) toAddress;
}

/*

// Solidity Interface:
contract NameReg{function kill(){}function register(bytes32 name){}function addressOf(bytes32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(bytes32 name){}}

// Example Solidity use:
NameReg(addrNameReg).register("Some Contract");

// JS Interface:
var abiNameReg = [{"constant":true,"inputs":[{"name":"name","type":"bytes32"}],"name":"addressOf","outputs":[{"name":"addr","type":"address"}]},{"constant":false,"inputs":[],"name":"kill","outputs":[]},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"nameOf","outputs":[{"name":"name","type":"bytes32"}]},{"constant":false,"inputs":[{"name":"name","type":"bytes32"}],"name":"register","outputs":[]},{"constant":false,"inputs":[],"name":"unregister","outputs":[]}];

// Example JS use:
web3.eth.contract(addrNameReg, abiNameReg).register("My Name").transact();

*/

//TODO: use imports
contract owned{function owned(){owner = msg.sender;}modifier onlyowner(){if(msg.sender==owner)_}address owner;}
contract mortal is owned {function kill() { if (msg.sender == owner) suicide(owner); }}

//sol Config
// Simple global configuration registrar.
// @authors:
//   Gav Wood <g@ethdev.com>

contract Config is mortal {
	function register(uint id, address service) {
		if (tx.origin != owner)
			return;
		services[id] = service;
		log1(0, bytes32(id));
	}

	function unregister(uint id) {
		if (msg.sender != owner && services[id] != msg.sender)
			return;
		services[id] = address(0);
		log1(0, bytes32(id));
	}

	function lookup(uint service) constant returns(address a) {
		return services[service];
	}

	mapping (uint => address) services;
}

/*

// Solidity Interface:
contract Config{function lookup(uint256 service)constant returns(address a){}function kill(){}function unregister(uint256 id){}function register(uint256 id,address service){}}

// Example Solidity use:
address addrConfig = 0xf025d81196b72fba60a1d4dddad12eeb8360d828;
address addrNameReg = Config(addrConfig).lookup(1);

// JS Interface:
var abiConfig = [{"constant":false,"inputs":[],"name":"kill","outputs":[]},{"constant":true,"inputs":[{"name":"service","type":"uint256"}],"name":"lookup","outputs":[{"name":"a","type":"address"}]},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"service","type":"address"}],"name":"register","outputs":[]},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"unregister","outputs":[]}];

// Example JS use:
var addrConfig = "0x661005d2720d855f1d9976f88bb10c1a3398c77f";
var addrNameReg;
web3.eth.contract(addrConfig, abiConfig).lookup(1).call().then(function(r){ addrNameReg = r; })

*/

//sol NameReg
// Simple global name registrar.
// @authors:
//   kobigurk (from #ethereum-dev)
//   Gav Wood <g@ethdev.com>

contract NameRegister {
	function getAddress(bytes32 _name) constant returns (address o_owner) {}
	function getName(address _owner) constant returns (bytes32 o_name) {}
}

contract NameReg is owned, NameRegister {
	function NameReg() {
		address addrConfig = 0xf025d81196b72fba60a1d4dddad12eeb8360d828;
		toName[addrConfig] = "Config";
		toAddress["Config"] = addrConfig;
		toName[this] = "NameReg";
		toAddress["NameReg"] = this;
		Config(addrConfig).register(1, this);
		//log1(0, bytes32(addrConfig));
		//log1(0, bytes32(this));
	}

	function register(bytes32 name) {
		// Don't allow the same name to be overwritten.
		if (toAddress[name] != address(0))
			return;
		// Unregister previous name if there was one.
		if (toName[msg.sender] != "")
			toAddress[toName[msg.sender]] = 0;

		toName[msg.sender] = name;
		toAddress[name] = msg.sender;
		//log1(0, bytes32(msg.sender));
	}

	function unregister() {
		bytes32 n = toName[msg.sender];
		if (n == "")
			return;
		//log1(0, bytes32(toAddress[n]));
		toName[msg.sender] = "";
		toAddress[n] = address(0);
	}

	function addressOf(bytes32 name) constant returns (address addr) {
		return toAddress[name];
	}

	function nameOf(address addr) constant returns (bytes32 name) {
		return toName[addr];
	}

	mapping (address => bytes32) toName;
	mapping (bytes32 => address) toAddress;
}

/*

// Solidity Interface:
contract NameReg{function kill(){}function register(bytes32 name){}function addressOf(bytes32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(bytes32 name){}}

// Example Solidity use:
NameReg(addrNameReg).register("Some Contract");

// JS Interface:
var abiNameReg = [{"constant":true,"inputs":[{"name":"name","type":"bytes32"}],"name":"addressOf","outputs":[{"name":"addr","type":"address"}]},{"constant":false,"inputs":[],"name":"kill","outputs":[]},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"nameOf","outputs":[{"name":"name","type":"bytes32"}]},{"constant":false,"inputs":[{"name":"name","type":"bytes32"}],"name":"register","outputs":[]},{"constant":false,"inputs":[],"name":"unregister","outputs":[]}];

// Example JS use:
web3.eth.contract(addrNameReg, abiNameReg).register("My Name").transact();

*/


Move input into state.

Move input into state.

pragma solidity ^0.4.0;

contract ScryptFramework {
    // The state object, can be used in both generating and verifying mode.
    // In generating mode, only vars and fullMemory is used, in verifying
    // mode only vars and memoryHash is used.
    struct State {
        // We need the input as part of the state because it is required
        // for the final step. We could move it to memory to shorten the state size.
        bytes input;
        uint[4] vars;
        bytes32 memoryHash;
        uint[] fullMemory;
    }
    // This is the witness data that is generated in generating mode
    // and used for verification in verification mode.
    struct Proofs {
        bool generateProofs;
        bytes proofs;
        uint readIndex;
        uint[4] vars;
        uint[4] read;
    }

    function inputToState(bytes memory input) pure internal returns (State memory state)
    {
        state.input = input;
        state.vars = KeyDeriv.pbkdf2(input, input, 128);
        state.vars[0] = Salsa8.endianConvert256bit(state.vars[0]);
        state.vars[1] = Salsa8.endianConvert256bit(state.vars[1]);
        state.vars[2] = Salsa8.endianConvert256bit(state.vars[2]);
        state.vars[3] = Salsa8.endianConvert256bit(state.vars[3]);
        initMemory(state);
    }

    function finalStateToOutput(State memory state) pure internal returns (bytes memory output)
    {
        state.vars[0] = Salsa8.endianConvert256bit(state.vars[0]);
        state.vars[1] = Salsa8.endianConvert256bit(state.vars[1]);
        state.vars[2] = Salsa8.endianConvert256bit(state.vars[2]);
        state.vars[3] = Salsa8.endianConvert256bit(state.vars[3]);
        bytes memory val = uint4ToBytes(state.vars);
        return uint4ToBytes(KeyDeriv.pbkdf2(state.input, val, 32));
    }

    function uint4ToBytes(uint[4] memory val) pure internal returns (bytes memory r)
    {
        r = new bytes(4 * 32);
        var v = val[0];
        assembly { mstore(add(r, 0x20), v) }
        v = val[1];
        assembly { mstore(add(r, 0x40), v) }
        v = val[2];
        assembly { mstore(add(r, 0x60), v) }
        v = val[3];
        assembly { mstore(add(r, 0x80), v) }
    }

    function initMemory(State memory state) pure internal;
    function writeMemory(State memory state, uint index, uint[4] values, Proofs memory proofs) pure internal;
    function readMemory(State memory state, uint index, Proofs memory proofs) pure internal returns (uint, uint, uint, uint);

    // Runs a single step, modifying state
    function runStep(State memory state, uint step, Proofs memory proofs) pure internal {
        require(step < 2048);
        if (step < 1024) {
            writeMemory(state, step, state.vars, proofs);
            state.vars = Salsa8.round(state.vars);
        } else {
            var readIndex = (state.vars[2] / 0x100000000000000000000000000000000000000000000000000000000) % 1024;
            proofs.readIndex = readIndex;
            var (va, vb, vc, vd) = readMemory(state, readIndex, proofs);
            proofs.vars = state.vars;
            proofs.read = [va, vb, vc, vd];
            state.vars = Salsa8.round([
                state.vars[0] ^ va,
                state.vars[1] ^ vb,
                state.vars[2] ^ vc,
                state.vars[3] ^ vd
            ]);
        }
    }
}

library Salsa8 {
    uint constant m0 = 0x100000000000000000000000000000000000000000000000000000000;
    uint constant m1 = 0x1000000000000000000000000000000000000000000000000;
    uint constant m2 = 0x010000000000000000000000000000000000000000;
    uint constant m3 = 0x100000000000000000000000000000000;
    uint constant m4 = 0x1000000000000000000000000;
    uint constant m5 = 0x10000000000000000;
    uint constant m6 = 0x100000000;
    uint constant m7 = 0x1;
    function quarter(uint32 y0, uint32 y1, uint32 y2, uint32 y3)
        pure internal returns (uint32, uint32, uint32, uint32)
    {
        uint32 t;
        t = y0 + y3;
        y1 = y1 ^ ((t * 2**7) | (t / 2**(32-7)));
        t = y1 + y0;
        y2 = y2 ^ ((t * 2**9) | (t / 2**(32-9)));
        t = y2 + y1;
        y3 = y3 ^ ((t * 2**13) | (t / 2**(32-13)));
        t = y3 + y2;
        y0 = y0 ^ ((t * 2**18) | (t / 2**(32-18)));
        return (y0, y1, y2, y3);
    }
    function get(uint data, uint word) pure internal returns (uint32 x)
    {
        return uint32(data / 2**(256 - word * 32 - 32));
    }
    function put(uint x, uint word) pure internal returns (uint) {
        return x * 2**(256 - word * 32 - 32);
    }
    function rowround(uint first, uint second) pure internal returns (uint f, uint s)
    {
        var (a,b,c,d) = quarter(uint32(first / m0), uint32(first / m1), uint32(first / m2), uint32(first / m3));
        f = (((((uint(a) * 2**32) | uint(b)) * 2 ** 32) | uint(c)) * 2**32) | uint(d);
        (b,c,d,a) = quarter(uint32(first / m5), uint32(first / m6), uint32(first / m7), uint32(first / m4));
        f = (((((((f * 2**32) | uint(a)) * 2**32) | uint(b)) * 2 ** 32) | uint(c)) * 2**32) | uint(d);
        (c,d,a,b) = quarter(uint32(second / m2), uint32(second / m3), uint32(second / m0), uint32(second / m1));
        s = (((((uint(a) * 2**32) | uint(b)) * 2 ** 32) | uint(c)) * 2**32) | uint(d);
        (d,a,b,c) = quarter(uint32(second / m7), uint32(second / m4), uint32(second / m5), uint32(second / m6));
        s = (((((((s * 2**32) | uint(a)) * 2**32) | uint(b)) * 2 ** 32) | uint(c)) * 2**32) | uint(d);
    }
    function columnround(uint first, uint second) pure internal returns (uint f, uint s)
    {
        var (a,b,c,d) = quarter(uint32(first / m0), uint32(first / m4), uint32(second / m0), uint32(second / m4));
        f = (uint(a) * m0) | (uint(b) * m4);
        s = (uint(c) * m0) | (uint(d) * m4);
        (a,b,c,d) = quarter(uint32(first / m5), uint32(second / m1), uint32(second / m5), uint32(first / m1));
        f |= (uint(a) * m5) | (uint(d) * m1);
        s |= (uint(b) * m1) | (uint(c) * m5);
        (a,b,c,d) = quarter(uint32(second / m2), uint32(second / m6), uint32(first / m2), uint32(first / m6));
        f |= (uint(c) * m2) | (uint(d) * m6);
        s |= (uint(a) * m2) | (uint(b) * m6);
        (a,b,c,d) = quarter(uint32(second / m7), uint32(first / m3), uint32(first / m7), uint32(second / m3));
        f |= (uint(b) * m3) | (uint(c) * m7);
        s |= (uint(a) * m7) | (uint(d) * m3);
    }
    function salsa20_8(uint _first, uint _second) pure internal returns (uint rfirst, uint rsecond) {
        uint first = _first;
        uint second = _second;
        for (uint i = 0; i < 8; i += 2)
        {
            (first, second) = columnround(first, second);
            (first, second) = rowround(first, second);
        }
        for (i = 0; i < 8; i++)
        {
            rfirst |= put(get(_first, i) + get(first, i), i);
            rsecond |= put(get(_second, i) + get(second, i), i);
        }
    }
    function endianConvert256bit(uint x) pure internal returns (uint) {
        return
            endianConvert32bit(x / m0) * m0 +
            endianConvert32bit(x / m1) * m1 +
            endianConvert32bit(x / m2) * m2 +
            endianConvert32bit(x / m3) * m3 +
            endianConvert32bit(x / m4) * m4 +
            endianConvert32bit(x / m5) * m5 +
            endianConvert32bit(x / m6) * m6 +
            endianConvert32bit(x / m7) * m7;
    }
    function endianConvert32bit(uint x) pure internal returns (uint) {
        return
            (x & 0xff) * 0x1000000 +
            (x & 0xff00) * 0x100 +
            (x & 0xff0000) / 0x100 +
            (x & 0xff000000) / 0x1000000;
    }

    function round(uint[4] values) pure internal returns (uint[4]) {
        var (a, b, c, d) = (values[0], values[1], values[2], values[3]);
        (a, b) = salsa20_8(a ^ c, b ^ d);
        (c, d) = salsa20_8(a ^ c, b ^ d);
        return [a, b, c, d];
    }
}

library KeyDeriv {
    function hmacsha256(bytes key, bytes message) pure internal returns (bytes32) {
        bytes32 keyl;
        bytes32 keyr;
        uint i;
        if (key.length > 64) {
            keyl = sha256(key);
        } else {
            for (i = 0; i < key.length && i < 32; i++)
                keyl |= bytes32(uint(key[i]) * 2**(8 * (31 - i)));
            for (i = 32; i < key.length && i < 64; i++)
                keyr |= bytes32(uint(key[i]) * 2**(8 * (63 - i)));
        }
        bytes32 threesix = 0x3636363636363636363636363636363636363636363636363636363636363636;
        bytes32 fivec = 0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c;
        return sha256(fivec ^ keyl, fivec ^ keyr, sha256(threesix ^ keyl, threesix ^ keyr, message));
    }
    /// PBKDF2 restricted to c=1, hash = hmacsha256 and dklen being a multiple of 32 not larger than 128
    function pbkdf2(bytes key, bytes salt, uint dklen) pure internal returns (uint[4] r) {
        var message = new bytes(salt.length + 4);
        for (uint i = 0; i < salt.length; i++)
            message[i] = salt[i];
        for (i = 0; i * 32 < dklen; i++) {
            message[message.length - 1] = bytes1(uint8(i + 1));
            r[i] = uint(hmacsha256(key, message));
        }
    }
}

pragma solidity ^0.4.0;

contract ScryptFramework {
    // The state object, can be used in both generating and verifying mode.
    // In generating mode, only vars and fullMemory is used, in verifying
    // mode only vars and memoryHash is used.
    struct State {
        uint[4] vars;
        bytes32 memoryHash;
        uint[] fullMemory;
    }
    // This is the witness data that is generated in generating mode
    // and used for verification in verification mode.
    struct Proofs {
        bool generateProofs;
        bytes proofs;
        uint readIndex;
        uint[4] vars;
        uint[4] read;
    }

    function inputToState(bytes memory input) pure internal returns (State memory state)
    {
        state.vars = KeyDeriv.pbkdf2(input, input, 128);
        state.vars[0] = Salsa8.endianConvert256bit(state.vars[0]);
        state.vars[1] = Salsa8.endianConvert256bit(state.vars[1]);
        state.vars[2] = Salsa8.endianConvert256bit(state.vars[2]);
        state.vars[3] = Salsa8.endianConvert256bit(state.vars[3]);
        initMemory(state);
    }

    function finalStateToOutput(State memory state) pure internal returns (bytes memory output)
    {
        state.vars[0] = Salsa8.endianConvert256bit(state.vars[0]);
        state.vars[1] = Salsa8.endianConvert256bit(state.vars[1]);
        state.vars[2] = Salsa8.endianConvert256bit(state.vars[2]);
        state.vars[3] = Salsa8.endianConvert256bit(state.vars[3]);
        bytes memory val = uint4ToBytes(state.vars);
        return uint4ToBytes(KeyDeriv.pbkdf2(val, val, 32));
    }

    function uint4ToBytes(uint[4] memory val) pure internal returns (bytes memory r)
    {
        r = new bytes(4 * 32);
        var v = val[0];
        assembly { mstore(add(r, 0x20), v) }
        v = val[1];
        assembly { mstore(add(r, 0x40), v) }
        v = val[2];
        assembly { mstore(add(r, 0x60), v) }
        v = val[3];
        assembly { mstore(add(r, 0x80), v) }
    }

    function initMemory(State memory state) pure internal;
    function writeMemory(State memory state, uint index, uint[4] values, Proofs memory proofs) pure internal;
    function readMemory(State memory state, uint index, Proofs memory proofs) pure internal returns (uint, uint, uint, uint);

    // Runs a single step, modifying state
    function runStep(State memory state, uint step, Proofs memory proofs) pure internal {
        require(step < 2048);
        if (step < 1024) {
            writeMemory(state, step, state.vars, proofs);
            state.vars = Salsa8.round(state.vars);
        } else {
            var readIndex = (state.vars[2] / 0x100000000000000000000000000000000000000000000000000000000) % 1024;
            proofs.readIndex = readIndex;
            var (va, vb, vc, vd) = readMemory(state, readIndex, proofs);
            proofs.vars = state.vars;
            proofs.read = [va, vb, vc, vd];
            state.vars = Salsa8.round([
                state.vars[0] ^ va,
                state.vars[1] ^ vb,
                state.vars[2] ^ vc,
                state.vars[3] ^ vd
            ]);
        }
    }
}

library Salsa8 {
    uint constant m0 = 0x100000000000000000000000000000000000000000000000000000000;
    uint constant m1 = 0x1000000000000000000000000000000000000000000000000;
    uint constant m2 = 0x010000000000000000000000000000000000000000;
    uint constant m3 = 0x100000000000000000000000000000000;
    uint constant m4 = 0x1000000000000000000000000;
    uint constant m5 = 0x10000000000000000;
    uint constant m6 = 0x100000000;
    uint constant m7 = 0x1;
    function quarter(uint32 y0, uint32 y1, uint32 y2, uint32 y3)
        pure internal returns (uint32, uint32, uint32, uint32)
    {
        uint32 t;
        t = y0 + y3;
        y1 = y1 ^ ((t * 2**7) | (t / 2**(32-7)));
        t = y1 + y0;
        y2 = y2 ^ ((t * 2**9) | (t / 2**(32-9)));
        t = y2 + y1;
        y3 = y3 ^ ((t * 2**13) | (t / 2**(32-13)));
        t = y3 + y2;
        y0 = y0 ^ ((t * 2**18) | (t / 2**(32-18)));
        return (y0, y1, y2, y3);
    }
    function get(uint data, uint word) pure internal returns (uint32 x)
    {
        return uint32(data / 2**(256 - word * 32 - 32));
    }
    function put(uint x, uint word) pure internal returns (uint) {
        return x * 2**(256 - word * 32 - 32);
    }
    function rowround(uint first, uint second) pure internal returns (uint f, uint s)
    {
        var (a,b,c,d) = quarter(uint32(first / m0), uint32(first / m1), uint32(first / m2), uint32(first / m3));
        f = (((((uint(a) * 2**32) | uint(b)) * 2 ** 32) | uint(c)) * 2**32) | uint(d);
        (b,c,d,a) = quarter(uint32(first / m5), uint32(first / m6), uint32(first / m7), uint32(first / m4));
        f = (((((((f * 2**32) | uint(a)) * 2**32) | uint(b)) * 2 ** 32) | uint(c)) * 2**32) | uint(d);
        (c,d,a,b) = quarter(uint32(second / m2), uint32(second / m3), uint32(second / m0), uint32(second / m1));
        s = (((((uint(a) * 2**32) | uint(b)) * 2 ** 32) | uint(c)) * 2**32) | uint(d);
        (d,a,b,c) = quarter(uint32(second / m7), uint32(second / m4), uint32(second / m5), uint32(second / m6));
        s = (((((((s * 2**32) | uint(a)) * 2**32) | uint(b)) * 2 ** 32) | uint(c)) * 2**32) | uint(d);
    }
    function columnround(uint first, uint second) pure internal returns (uint f, uint s)
    {
        var (a,b,c,d) = quarter(uint32(first / m0), uint32(first / m4), uint32(second / m0), uint32(second / m4));
        f = (uint(a) * m0) | (uint(b) * m4);
        s = (uint(c) * m0) | (uint(d) * m4);
        (a,b,c,d) = quarter(uint32(first / m5), uint32(second / m1), uint32(second / m5), uint32(first / m1));
        f |= (uint(a) * m5) | (uint(d) * m1);
        s |= (uint(b) * m1) | (uint(c) * m5);
        (a,b,c,d) = quarter(uint32(second / m2), uint32(second / m6), uint32(first / m2), uint32(first / m6));
        f |= (uint(c) * m2) | (uint(d) * m6);
        s |= (uint(a) * m2) | (uint(b) * m6);
        (a,b,c,d) = quarter(uint32(second / m7), uint32(first / m3), uint32(first / m7), uint32(second / m3));
        f |= (uint(b) * m3) | (uint(c) * m7);
        s |= (uint(a) * m7) | (uint(d) * m3);
    }
    function salsa20_8(uint _first, uint _second) pure internal returns (uint rfirst, uint rsecond) {
        uint first = _first;
        uint second = _second;
        for (uint i = 0; i < 8; i += 2)
        {
            (first, second) = columnround(first, second);
            (first, second) = rowround(first, second);
        }
        for (i = 0; i < 8; i++)
        {
            rfirst |= put(get(_first, i) + get(first, i), i);
            rsecond |= put(get(_second, i) + get(second, i), i);
        }
    }
    function endianConvert256bit(uint x) pure internal returns (uint) {
        return
            endianConvert32bit(x / m0) * m0 +
            endianConvert32bit(x / m1) * m1 +
            endianConvert32bit(x / m2) * m2 +
            endianConvert32bit(x / m3) * m3 +
            endianConvert32bit(x / m4) * m4 +
            endianConvert32bit(x / m5) * m5 +
            endianConvert32bit(x / m6) * m6 +
            endianConvert32bit(x / m7) * m7;
    }
    function endianConvert32bit(uint x) pure internal returns (uint) {
        return
            (x & 0xff) * 0x1000000 +
            (x & 0xff00) * 0x100 +
            (x & 0xff0000) / 0x100 +
            (x & 0xff000000) / 0x1000000;
    }

    function round(uint[4] values) pure internal returns (uint[4]) {
        var (a, b, c, d) = (values[0], values[1], values[2], values[3]);
        (a, b) = salsa20_8(a ^ c, b ^ d);
        (c, d) = salsa20_8(a ^ c, b ^ d);
        return [a, b, c, d];
    }
}

library KeyDeriv {
    function hmacsha256(bytes key, bytes message) pure internal returns (bytes32) {
        bytes32 keyl;
        bytes32 keyr;
        uint i;
        if (key.length > 64) {
            keyl = sha256(key);
        } else {
            for (i = 0; i < key.length && i < 32; i++)
                keyl |= bytes32(uint(key[i]) * 2**(8 * (31 - i)));
            for (i = 32; i < key.length && i < 64; i++)
                keyr |= bytes32(uint(key[i]) * 2**(8 * (63 - i)));
        }
        bytes32 threesix = 0x3636363636363636363636363636363636363636363636363636363636363636;
        bytes32 fivec = 0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c;
        return sha256(fivec ^ keyl, fivec ^ keyr, sha256(threesix ^ keyl, threesix ^ keyr, message));
    }
    /// PBKDF2 restricted to c=1, hash = hmacsha256 and dklen being a multiple of 32 not larger than 128
    function pbkdf2(bytes key, bytes salt, uint dklen) pure internal returns (uint[4] r) {
        var message = new bytes(salt.length + 4);
        for (uint i = 0; i < salt.length; i++)
            message[i] = salt[i];
        for (i = 0; i * 32 < dklen; i++) {
            message[message.length - 1] = bytes1(uint8(i + 1));
            r[i] = uint(hmacsha256(key, message));
        }
    }
}


add Event GameStateChanged to move, add call makeTemporaryMove to move

/**
 * 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 {
    int8[128] defaultState = [int8(-4),int8(-2),int8(-3),int8(-5),int8(-6),int8(-3),int8(-2),int8(-4),int8(0),int8(0),int8(0),int8(4),int8(0),int8(0),int8(0),int8(0),int8(-1),int8(-1),int8(-1),int8(-1),int8(-1),int8(-1),int8(-1),int8(-1),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(1),int8(1),int8(1),int8(1),int8(1),int8(1),int8(1),int8(1),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(4),int8(2),int8(3),int8(5),int8(6),int8(3),int8(2),int8(4),int8(0),int8(0),int8(0),int8(116),int8(0),int8(0),int8(0),int8(0)];

    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[uint(Flag.FLAG_NAME)]
     * Directions[Direction.UP]
     */
    enum Direction { UP, UP_RIGHT, RIGHT, DOWN_RIGHT, DOWN, DOWN_LEFT, LEFT, UP_LEFT }
    int8[8] Directions = [int8(-16), int8(-15), int8(1), int8(17), int8(16), int8(15), int8(-1), int8(-17)];
    enum Piece { WHITE_KING, WHITE_QUEEN, WHITE_ROOK, WHITE_BISHOP, WHITE_KNIGHT, WHITE_PAWN, EMPTY, BLACK_KING, BLACK_QUEEN, BLACK_ROOK, BLACK_BISHOP, BLACK_KNIGHT, BLACK_PAWN }
    int8[13] Pieces = [int8(-6), int8(-5), int8(-4), int8(-3), int8(-2), int8(-1), int8(0), int8(6), int8(5), int8(4), int8(3), int8(2), int8(1)];
    enum Player { WHITE, BLACK }
    int8[2] Players = [int8(1), int8(-1)];
    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}
    int8[9] Flags = [int8(123), int8(11), int8(16), int8(78), int8(79), int8(62), int8(63), int8(61), int8(77)];

    int8[8] knight_moves = [int8(-33), int8(-31), int8(-18), int8(-14), int8(14), int8(18), int8(31), int8(33)];

    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, uint value) internal {
        games[gameId].state[uint(Flags[uint(flag)])] = int8(value);
    }

    /**
     * Convenience function to set a flag
     * Usage: setFlag(gameId, Flag.BLACK_KING_POS, 4);
     */
    function getFlag(bytes32 gameId, Flag flag) internal returns (int8) {
        return games[gameId].state[uint(Flags[uint(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
        games[gameId].state = defaultState;

        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 P2
            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[uint(Player.WHITE)];
        } else {
            currentPlayerColor = Players[uint(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[uint(Piece.BLACK_KNIGHT)])) {
            bool checkForCheck = abs(fromFigure) == uint(Pieces[uint(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) {
            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)
        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[uint(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[uint(Piece.BLACK_KING)]) {
                if (4 == fromIndex && toFigure == 0) {
                    if (toIndex == 1 && getFlag(gameId, Flag.BLACK_LEFT_CASTLING) >= 0) {
                        return;
                    }
                    if (toIndex == 6 && getFlag(gameId, Flag.BLACK_RIGHT_CASTLING) >= 0) {
                        return;
                    }
                }
            }
            if (fromFigure == Pieces[uint(Piece.WHITE_KING)]) {
                if (116 == fromIndex && toFigure == 0) {
                    if (toIndex == 113 && 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[uint(Piece.BLACK_BISHOP)]) ||
            abs(fromFigure) == uint(Pieces[uint(Piece.BLACK_QUEEN)]) ||
            abs(fromFigure) == uint(Pieces[uint(Piece.BLACK_ROOK)])) {

            if (!isDiagonal && abs(fromFigure) == uint(Pieces[uint(Piece.BLACK_BISHOP)]) ||
                isDiagonal && abs(fromFigure) == uint(Pieces[uint(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[uint(Piece.BLACK_PAWN)])) {
            // Black can only move in positive, White negative direction
            if (fromFigure == Pieces[uint(Piece.BLACK_PAWN)] && direction < 0 ||
                fromFigure == Pieces[uint(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[uint(Piece.BLACK_PAWN)] &&
                        getFlag(gameId, Flag.WHITE_EN_PASSANT) == int(toIndex) ||
                        fromFigure == Pieces[uint(Piece.WHITE_PAWN)] &&
                        getFlag(gameId, Flag.BLACK_EN_PASSANT) == int(toIndex)) {
                        return;
                    }
                }
                // If not empty
                return;
            }

            throw;
        }

        // Knights
        if (abs(fromFigure) == uint(Pieces[uint(Piece.BLACK_KNIGHT)])) {
            for (uint i; i < knight_moves.length; i++) {
                if (int(fromIndex) + knight_moves[i] == 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[uint(Direction.UP)];
            }
            if (isSameHorizontal){
                return Directions[uint(Direction.LEFT)];
            }
            if (isLeftSide){
                return Directions[uint(Direction.UP_LEFT)];
            } else {
                return Directions[uint(Direction.UP_RIGHT)];
            }
        } else {
            if (isSameVertical){
                return Directions[uint(Direction.DOWN)];
            }
            if (isSameHorizontal){
                return Directions[uint(Direction.RIGHT)];
            }
            if (isLeftSide){
                return Directions[uint(Direction.DOWN_LEFT)];
            } else{
                return Directions[uint(Direction.DOWN_RIGHT)];
            }
        }
    }

    function makeTemporaryMove(bytes32 gameId, uint256 fromIndex, uint256 toIndex, int8 fromFigure, int8 toFigure){
        games[gameId].state[uint(Flags[uint(Flag.WHITE_EN_PASSANT)])] = -1;
        games[gameId].state[uint(Flags[uint(Flag.WHITE_EN_PASSANT)])] = -1;

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

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

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

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

        }

        //Remove Castling Flag

        // Black
        if (fromFigure == Pieces[uint(Piece.BLACK_KING)]){
            if (fromIndex == 4){
                Flags[uint(Flag.BLACK_LEFT_CASTLING)] = -1;
                Flags[uint(Flag.BLACK_RIGHT_CASTLING)] = -1;
            }
        }
        if (fromFigure == Pieces[uint(Piece.BLACK_ROOK)]){
            if (fromIndex == 0){
                Flags[uint(Flag.BLACK_LEFT_CASTLING)] = -1;
            }
            if (fromIndex == 7){
                Flags[uint(Flag.BLACK_RIGHT_CASTLING)] = -1;
            }
        }

        // White
        if (fromFigure == Pieces[uint(Piece.WHITE_KING)]){
            if (fromIndex == 116){
                Flags[uint(Flag.WHITE_LEFT_CASTLING)] = -1;
                Flags[uint(Flag.WHITE_RIGHT_CASTLING)] = -1;
            }
        }
        if (fromFigure == Pieces[uint(Piece.WHITE_ROOK)]){
            if (fromIndex == 112){
                Flags[uint(Flag.WHITE_LEFT_CASTLING)] = -1;
            }
            if (fromIndex == 119){
                Flags[uint(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[uint(dir)]) == 16)
        return false;
      if(abs(Directions[uint(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 {
    int8[128] defaultState = [int8(-4),int8(-2),int8(-3),int8(-5),int8(-6),int8(-3),int8(-2),int8(-4),int8(0),int8(0),int8(0),int8(4),int8(0),int8(0),int8(0),int8(0),int8(-1),int8(-1),int8(-1),int8(-1),int8(-1),int8(-1),int8(-1),int8(-1),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(1),int8(1),int8(1),int8(1),int8(1),int8(1),int8(1),int8(1),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(0),int8(4),int8(2),int8(3),int8(5),int8(6),int8(3),int8(2),int8(4),int8(0),int8(0),int8(0),int8(116),int8(0),int8(0),int8(0),int8(0)];

    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[uint(Flag.FLAG_NAME)]
     * Directions[Direction.UP]
     */
    enum Direction { UP, UP_RIGHT, RIGHT, DOWN_RIGHT, DOWN, DOWN_LEFT, LEFT, UP_LEFT }
    int8[8] Directions = [int8(-16), int8(-15), int8(1), int8(17), int8(16), int8(15), int8(-1), int8(-17)];
    enum Piece { WHITE_KING, WHITE_QUEEN, WHITE_ROOK, WHITE_BISHOP, WHITE_KNIGHT, WHITE_PAWN, EMPTY, BLACK_KING, BLACK_QUEEN, BLACK_ROOK, BLACK_BISHOP, BLACK_KNIGHT, BLACK_PAWN }
    int8[13] Pieces = [int8(-6), int8(-5), int8(-4), int8(-3), int8(-2), int8(-1), int8(0), int8(6), int8(5), int8(4), int8(3), int8(2), int8(1)];
    enum Player { WHITE, BLACK }
    int8[2] Players = [int8(1), int8(-1)];
    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}
    int8[9] Flags = [int8(123), int8(11), int8(16), int8(78), int8(79), int8(62), int8(63), int8(61), int8(77)];

    int8[8] knight_moves = [int8(-33), int8(-31), int8(-18), int8(-14), int8(14), int8(18), int8(31), int8(33)];

    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, uint value) internal {
        games[gameId].state[uint(Flags[uint(flag)])] = int8(value);
    }

    /**
     * Convenience function to set a flag
     * Usage: setFlag(gameId, Flag.BLACK_KING_POS, 4);
     */
    function getFlag(bytes32 gameId, Flag flag) internal returns (int8) {
        return games[gameId].state[uint(Flags[uint(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
        games[gameId].state = defaultState;

        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 P2
            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[uint(Player.WHITE)];
        } else {
            currentPlayerColor = Players[uint(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[uint(Piece.BLACK_KNIGHT)])) {
            bool checkForCheck = abs(fromFigure) == uint(Pieces[uint(Piece.BLACK_KING)]);
            checkWayFree(gameId, fromIndex, toIndex, currentPlayerColor, checkForCheck);
        }

        //makeTemporaryMove

        //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);
    }

    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) {
            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)
        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[uint(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[uint(Piece.BLACK_KING)]) {
                if (4 == fromIndex && toFigure == 0) {
                    if (toIndex == 1 && getFlag(gameId, Flag.BLACK_LEFT_CASTLING) >= 0) {
                        return;
                    }
                    if (toIndex == 6 && getFlag(gameId, Flag.BLACK_RIGHT_CASTLING) >= 0) {
                        return;
                    }
                }
            }
            if (fromFigure == Pieces[uint(Piece.WHITE_KING)]) {
                if (116 == fromIndex && toFigure == 0) {
                    if (toIndex == 113 && 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[uint(Piece.BLACK_BISHOP)]) ||
            abs(fromFigure) == uint(Pieces[uint(Piece.BLACK_QUEEN)]) ||
            abs(fromFigure) == uint(Pieces[uint(Piece.BLACK_ROOK)])) {

            if (!isDiagonal && abs(fromFigure) == uint(Pieces[uint(Piece.BLACK_BISHOP)]) ||
                isDiagonal && abs(fromFigure) == uint(Pieces[uint(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[uint(Piece.BLACK_PAWN)])) {
            // Black can only move in positive, White negative direction
            if (fromFigure == Pieces[uint(Piece.BLACK_PAWN)] && direction < 0 ||
                fromFigure == Pieces[uint(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[uint(Piece.BLACK_PAWN)] &&
                        getFlag(gameId, Flag.WHITE_EN_PASSANT) == int(toIndex) ||
                        fromFigure == Pieces[uint(Piece.WHITE_PAWN)] &&
                        getFlag(gameId, Flag.BLACK_EN_PASSANT) == int(toIndex)) {
                        return;
                    }
                }
                // If not empty
                return;
            }

            throw;
        }

        // Knights
        if (abs(fromFigure) == uint(Pieces[uint(Piece.BLACK_KNIGHT)])) {
            for (uint i; i < knight_moves.length; i++) {
                if (int(fromIndex) + knight_moves[i] == 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[uint(Direction.UP)];
            }
            if (isSameHorizontal){
                return Directions[uint(Direction.LEFT)];
            }
            if (isLeftSide){
                return Directions[uint(Direction.UP_LEFT)];
            } else {
                return Directions[uint(Direction.UP_RIGHT)];
            }
        } else {
            if (isSameVertical){
                return Directions[uint(Direction.DOWN)];
            }
            if (isSameHorizontal){
                return Directions[uint(Direction.RIGHT)];
            }
            if (isLeftSide){
                return Directions[uint(Direction.DOWN_LEFT)];
            } else{
                return Directions[uint(Direction.DOWN_RIGHT)];
            }
        }
    }

    function makeTemporaryMove(bytes32 gameId, uint256 fromIndex, uint256 toIndex, int8 fromFigure, int8 toFigure){
        games[gameId].state[uint(Flags[uint(Flag.WHITE_EN_PASSANT)])] = -1;
        games[gameId].state[uint(Flags[uint(Flag.WHITE_EN_PASSANT)])] = -1;

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

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

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

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

        }

        //Remove Castling Flag

        // Black
        if (fromFigure == Pieces[uint(Piece.BLACK_KING)]){
            if (fromIndex == 4){
                Flags[uint(Flag.BLACK_LEFT_CASTLING)] = -1;
                Flags[uint(Flag.BLACK_RIGHT_CASTLING)] = -1;
            }
        }
        if (fromFigure == Pieces[uint(Piece.BLACK_ROOK)]){
            if (fromIndex == 0){
                Flags[uint(Flag.BLACK_LEFT_CASTLING)] = -1;
            }
            if (fromIndex == 7){
                Flags[uint(Flag.BLACK_RIGHT_CASTLING)] = -1;
            }
        }

        // White
        if (fromFigure == Pieces[uint(Piece.WHITE_KING)]){
            if (fromIndex == 116){
                Flags[uint(Flag.WHITE_LEFT_CASTLING)] = -1;
                Flags[uint(Flag.WHITE_RIGHT_CASTLING)] = -1;
            }
        }
        if (fromFigure == Pieces[uint(Piece.WHITE_ROOK)]){
            if (fromIndex == 112){
                Flags[uint(Flag.WHITE_LEFT_CASTLING)] = -1;
            }
            if (fromIndex == 119){
                Flags[uint(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[uint(dir)]) == 16)
        return false;
      if(abs(Directions[uint(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
    }
}


Splitter Contract skeleton. Perhaps we would like to log when a split transaction has a remainder. Also what should we do with the remainder, we could send it back now; store it against the sender recipient; or simply give it away to one of the receipient. While I'm here, should Events be named Log<Function>Event? Or is just Log<Function> fine.


foundry tests (BondingManagerForceChangeDelegateFix): add back test to validate 'Bond' event

pragma solidity ^0.8.9;

import "ds-test/test.sol";
import "./base/GovernorBaseTest.sol";
import "contracts/Controller.sol";
import "contracts/bonding/BondingManager.sol";
import "contracts/snapshots/MerkleSnapshot.sol";
import "./interfaces/ICheatCodes.sol";
import "./interfaces/IL2Migrator.sol";

// forge test --match-contract BondingManagerForceChangeDelegateFix --fork-url https://arbitrum-mainnet.infura.io/v3/<INFURA_KEY> -vvv --fork-block-number 8006620
contract BondingManagerForceChangeDelegateFix is GovernorBaseTest {
    BondingManager public constant BONDING_MANAGER = BondingManager(0x35Bcf3c30594191d53231E4FF333E8A770453e40);
    MerkleSnapshot public constant MERKLE_SNAPSHOT = MerkleSnapshot(0x10736ffaCe687658F88a46D042631d182C7757f7);
    IL2Migrator public constant L2_MIGRATOR = IL2Migrator(0x148D5b6B4df9530c7C76A810bd1Cdf69EC4c2085);

    bytes32 public constant BONDING_MANAGER_TARGET_ID = keccak256("BondingManagerTarget");

    BondingManager public newBondingManagerTarget;

    event Bond(
        address indexed newDelegate,
        address indexed oldDelegate,
        address indexed delegator,
        uint256 additionalAmount,
        uint256 bondedAmount
    );

    function setUp() public {
        newBondingManagerTarget = new BondingManager(address(CONTROLLER));

        (, gitCommitHash) = CONTROLLER.getContractInfo(BONDING_MANAGER_TARGET_ID);

        uint256 round = 2499;
        uint256 blockNum = round * 5760;
        CHEATS.roll(blockNum);

        stageAndExecuteOne(
            address(CONTROLLER),
            0,
            abi.encodeWithSelector(
                CONTROLLER.setContractInfo.selector,
                BONDING_MANAGER_TARGET_ID,
                address(newBondingManagerTarget),
                gitCommitHash
            )
        );
    }

    function testUpgrade() public {
        // Check that new BondingManagerTarget is registered
        (address infoAddr, bytes20 infoGitCommitHash) = fetchContractInfo(BONDING_MANAGER_TARGET_ID);
        assertEq(infoAddr, address(newBondingManagerTarget));
        assertEq(infoGitCommitHash, gitCommitHash);
    }

    function testBond() public {
        address delegator = 0x5Ec2be1aDC70Bc338471277c2dCc183b0b2C91be;
        (, , address delegateAddress, , , , ) = BONDING_MANAGER.getDelegator(delegator);

        uint256 initialStake = BONDING_MANAGER.transcoderTotalStake(delegateAddress);

        CHEATS.prank(delegator);
        BONDING_MANAGER.bond(10, delegateAddress);

        uint256 finalStake = BONDING_MANAGER.transcoderTotalStake(delegateAddress);

        assertEq(finalStake, initialStake + 10);
    }

    function testChangeDelegate() public {
        address delegator = 0xAcA4bD77e459b9898A0de9Ad7C1caC34fF540D0B;
        address delegate = 0x525419FF5707190389bfb5C87c375D710F5fCb0E;

        // checks if owner can change delegate
        CHEATS.prank(delegator);
        BONDING_MANAGER.bond(0, delegate);

        (, , address delegateAddress, , , , ) = BONDING_MANAGER.getDelegator(delegator);

        assertEq(delegateAddress, delegate);
    }

    function testClaimStake() public {
        CHEATS.mockCall(
            address(MERKLE_SNAPSHOT),
            abi.encodeWithSelector(MERKLE_SNAPSHOT.verify.selector),
            abi.encode(true)
        );

        address delegator = 0xE22d48950C88C4e8F2C5dA6c7d32D4bc9fE43Bff;
        address delegate = 0x91f19C0335BC776f4693EeB1D88765243f63e9D6;

        bytes32[] memory proof;

        CHEATS.prank(delegator);
        CHEATS.expectEmit(true, true, true, true);
        emit Bond(delegate, address(0), delegator, 500000000000000000000, 500000000000000000000);
        L2_MIGRATOR.claimStake(delegate, 500000000000000000000, 0, proof, address(0));

        (, , address delegateAddress, , , , ) = BONDING_MANAGER.getDelegator(delegator);

        assertEq(delegateAddress, delegate);
    }

    function testChangeDelegateByThirdParty() public {
        address delegator = 0xAcA4bD77e459b9898A0de9Ad7C1caC34fF540D0B;
        address delegate = 0x525419FF5707190389bfb5C87c375D710F5fCb0E;
        address thirdParty = 0x12336b564A71Cc4C1319bf35E87Ea45681E4D94a;

        // trying to change delegate of a delegator should revert
        CHEATS.prank(thirdParty);
        CHEATS.expectRevert(bytes("INVALID_CALLER"));
        BONDING_MANAGER.bondForWithHint(0, delegator, delegate, address(0), address(0), address(0), address(0));
    }
}

pragma solidity ^0.8.9;

import "ds-test/test.sol";
import "./base/GovernorBaseTest.sol";
import "contracts/Controller.sol";
import "contracts/bonding/BondingManager.sol";
import "contracts/snapshots/MerkleSnapshot.sol";
import "./interfaces/ICheatCodes.sol";
import "./interfaces/IL2Migrator.sol";

// forge test --match-contract BondingManagerForceChangeDelegateFix --fork-url https://arbitrum-mainnet.infura.io/v3/<INFURA_KEY> -vvv --fork-block-number 8006620
contract BondingManagerForceChangeDelegateFix is GovernorBaseTest {
    BondingManager public constant BONDING_MANAGER = BondingManager(0x35Bcf3c30594191d53231E4FF333E8A770453e40);
    MerkleSnapshot public constant MERKLE_SNAPSHOT = MerkleSnapshot(0x10736ffaCe687658F88a46D042631d182C7757f7);
    IL2Migrator public constant L2_MIGRATOR = IL2Migrator(0x148D5b6B4df9530c7C76A810bd1Cdf69EC4c2085);

    bytes32 public constant BONDING_MANAGER_TARGET_ID = keccak256("BondingManagerTarget");

    BondingManager public newBondingManagerTarget;

    function setUp() public {
        newBondingManagerTarget = new BondingManager(address(CONTROLLER));

        (, gitCommitHash) = CONTROLLER.getContractInfo(BONDING_MANAGER_TARGET_ID);

        uint256 round = 2499;
        uint256 blockNum = round * 5760;
        CHEATS.roll(blockNum);

        stageAndExecuteOne(
            address(CONTROLLER),
            0,
            abi.encodeWithSelector(
                CONTROLLER.setContractInfo.selector,
                BONDING_MANAGER_TARGET_ID,
                address(newBondingManagerTarget),
                gitCommitHash
            )
        );
    }

    function testUpgrade() public {
        // Check that new BondingManagerTarget is registered
        (address infoAddr, bytes20 infoGitCommitHash) = fetchContractInfo(BONDING_MANAGER_TARGET_ID);
        assertEq(infoAddr, address(newBondingManagerTarget));
        assertEq(infoGitCommitHash, gitCommitHash);
    }

    function testBond() public {
        address delegator = 0x5Ec2be1aDC70Bc338471277c2dCc183b0b2C91be;
        (, , address delegateAddress, , , , ) = BONDING_MANAGER.getDelegator(delegator);

        uint256 initialStake = BONDING_MANAGER.transcoderTotalStake(delegateAddress);

        CHEATS.prank(delegator);
        BONDING_MANAGER.bond(10, delegateAddress);

        uint256 finalStake = BONDING_MANAGER.transcoderTotalStake(delegateAddress);

        assertEq(finalStake, initialStake + 10);
    }

    function testChangeDelegate() public {
        address delegator = 0xAcA4bD77e459b9898A0de9Ad7C1caC34fF540D0B;
        address delegate = 0x525419FF5707190389bfb5C87c375D710F5fCb0E;

        // checks if owner can change delegate
        CHEATS.prank(delegator);
        BONDING_MANAGER.bond(0, delegate);

        (, , address delegateAddress, , , , ) = BONDING_MANAGER.getDelegator(delegator);

        assertEq(delegateAddress, delegate);
    }

    function testClaimStake() public {
        CHEATS.mockCall(
            address(MERKLE_SNAPSHOT),
            abi.encodeWithSelector(MERKLE_SNAPSHOT.verify.selector),
            abi.encode(true)
        );

        address delegator = 0xE22d48950C88C4e8F2C5dA6c7d32D4bc9fE43Bff;
        address delegate = 0x91f19C0335BC776f4693EeB1D88765243f63e9D6;

        bytes32[] memory proof;
        CHEATS.prank(delegator);

        L2_MIGRATOR.claimStake(delegate, 500000000000000000000, 0, proof, address(0));

        (, , address delegateAddress, , , , ) = BONDING_MANAGER.getDelegator(delegator);

        assertEq(delegateAddress, delegate);
    }

    function testChangeDelegateByThirdParty() public {
        address delegator = 0xAcA4bD77e459b9898A0de9Ad7C1caC34fF540D0B;
        address delegate = 0x525419FF5707190389bfb5C87c375D710F5fCb0E;
        address thirdParty = 0x12336b564A71Cc4C1319bf35E87Ea45681E4D94a;

        // trying to change delegate of a delegator should revert
        CHEATS.prank(thirdParty);
        CHEATS.expectRevert(bytes("INVALID_CALLER"));
        BONDING_MANAGER.bondForWithHint(0, delegator, delegate, address(0), address(0), address(0), address(0));
    }
}


change seed for different calls to getRandom

pragma solidity ^0.4.11;

import "./FathomToken.sol";
import "./ConceptRegistry.sol";
import "./Assessment.sol";
import "./Math.sol";

//@purpose: To store concept data and create and manage assessments and members
contract Concept {
    address[] public parents; //The concepts that this concept is child to (ie: Calculus is child to Math)
    bytes data;
    address public fathomToken;
    address conceptRegistry;
    uint public lifetime;
    mapping (address => bool) public assessmentExists;

    uint[] propagationRates;

    address[] public members;
    mapping (address => MemberData) memberData;

    struct MemberData {
        address recentAssessment;
        uint index;
        ComponentWeight[] weights;
        mapping(address => uint) componentWeightIndex;
    }

    struct ComponentWeight {
        uint weight;
        uint date;
    }

    modifier onlyConcept() {
        require(ConceptRegistry(conceptRegistry).conceptExists(msg.sender));
        _;
    }

    function Concept(address[] _parents, uint[] _propagationRates, uint _lifetime, bytes _data) {
        require(_parents.length == _propagationRates.length);
        conceptRegistry = msg.sender;

        for (uint j=0; j < _parents.length; j++) {
            require(ConceptRegistry(conceptRegistry).conceptExists(_parents[j]));
            require(_propagationRates[j] <= 1000);
        }

        propagationRates = _propagationRates;
        parents = _parents;
        data = _data;
        lifetime = _lifetime;
        fathomToken = ConceptRegistry(conceptRegistry).fathomToken();
    }

    function getMemberLength() constant returns(uint) {
        return members.length;
    }

    function getParentsLength() constant returns(uint) {
        return parents.length;
    }

    /*
      @purpose: To add the firstUser to Mew
    */
    function addInitialMember(address _user, uint _weight) {
        if (ConceptRegistry(conceptRegistry).distributorAddress() == msg.sender)
            {
                this.addWeight(_user, _weight);
            }
    }

    /*
      @purpose: add the caller of this function to the arrays of potential assessors
      if they still have a weight in the concept
      @returns true if they are available as assessor
    */
    function setAvailability() returns(bool success){
        if (getWeight(msg.sender) > 0) {
            if (memberData[msg.sender].index == 0) {
                members.push(msg.sender);
                memberData[msg.sender].index = members.length;
                success = true;
            }
            else {
                removeMember(msg.sender);
            }
        }
   }

    /*
      //@purpose: returns a random member of the Concept or the zero address (both with approx. 50%)
      //Users with high weights are more likely to be called
      //@returns the address of the member (0x0 if there is no member)
    */
    function getWeightedRandomMember(uint seed) returns(address){
        uint weight1;
        uint weight2;
        address randomMember1;
        while (members.length > 1 && weight1 == 0) {
            uint index1 = Math.getRandom(seed, members.length - 1);
            randomMember1 = members[index1];
            weight1 = getWeight(randomMember1);
            seed++;
        }
        while (members.length > 1 && weight2 == 0) {
                uint index2 = Math.getRandom(seed * 2, members.length - 1);
                address randomMember2 = members[index2];
                weight2 = getWeight(randomMember2);
                seed += 10;
        }
        if (weight1 > weight2) {
            return randomMember1;
        }
    }

    /*
      @purpose: get the weight of a given member, also removes that member from the array
      if there legitimating assessment is expired
    */
    function getWeight(address _member) returns(uint weight){
        for (uint i=0; i < memberData[_member].weights.length; i++) {
            if (memberData[_member].weights[i].date > now){
                weight += memberData[_member].weights[i].weight;
            }
        }
        if (weight == 0) {
            removeMember(_member);
        }
    }
    /*
      @purpose: removes member at a given index from the members array by substituting they with
      the last member and then decreasing the size of the members array
      @returns the updated number of members in the concept
    */
    function removeMember(address _member) internal returns(uint){
        uint index = memberData[_member].index;
        if (index > 0){
            members[index] = members[members.length - 1]; //THIS NEEDS TO BE TESTED!
            memberData[_member].index = 0;
            members.length--;
        }
        return members.length;
    }

    /*
      @purpose: To make a new assessment
      @param: uint cost = the cost per assessor
      @param: uint size = the number of assessors
    */
    function makeAssessment(uint cost, uint size, uint _waitTime, uint _timeLimit) returns(bool) {
        if (size >= 5 && this.subtractBalance(msg.sender, cost*size)) {
            Assessment newAssessment = new Assessment(msg.sender, size, cost, _waitTime, _timeLimit);
            assessmentExists[address(newAssessment)] = true;
            newAssessment.setAssessorPool(block.number, address(this), size*5); //assemble the assessorPool by relevance
            return true;
        }
        else {
            return false;
        }
    }

    /*
      @purpose: To add a member to a concept and to recursively add  a member to parent concept
      @param: address assessee = the address of the assessee
      @param: uint weight = the weight for the member
      @returns: nothing
    */
    function addMember(address _assessee, uint _weight) {
        if (assessmentExists[msg.sender]) {
            memberData[_assessee].recentAssessment = msg.sender;
            memberData[_assessee].index = 0;
            this.addWeight(_assessee, _weight);
        }
    }
    function addWeight(address _assessee, uint _weight) onlyConcept() {
        if (memberData[_assessee].index == 0) {
            members.push(_assessee);
            memberData[_assessee].index = members.length;
        }

        uint idx = memberData[_assessee].componentWeightIndex[msg.sender];
        if (idx > 0) {
            memberData[_assessee].weights[idx-1] = ComponentWeight(_weight, now + lifetime);
        } else {
            memberData[_assessee].weights.push(ComponentWeight(_weight, now + lifetime));
            memberData[_assessee].componentWeightIndex[msg.sender] = memberData[_assessee].weights.length;
        }

        for(uint i = 0; i < parents.length; i++) {
            if((_weight*propagationRates[i])/1000 > 0) {
                Concept(parents[i]).addWeight(_assessee, (_weight*propagationRates[i])/1000);
            }
        }
    }

    function subtractBalance(address _from, uint _amount) returns(bool) {
        if (assessmentExists[msg.sender] || msg.sender == address(this)) {
            return FathomToken(fathomToken).subtractBalance(_from, _amount);
        }
        return false;
    }
}

pragma solidity ^0.4.11;

import "./FathomToken.sol";
import "./ConceptRegistry.sol";
import "./Assessment.sol";
import "./Math.sol";

//@purpose: To store concept data and create and manage assessments and members
contract Concept {
    address[] public parents; //The concepts that this concept is child to (ie: Calculus is child to Math)
    bytes data;
    address public fathomToken;
    address conceptRegistry;
    uint public lifetime;
    mapping (address => bool) public assessmentExists;

    uint[] propagationRates;

    address[] public members;
    mapping (address => MemberData) memberData;

    struct MemberData {
        address recentAssessment;
        uint index;
        ComponentWeight[] weights;
        mapping(address => uint) componentWeightIndex;
    }

    struct ComponentWeight {
        uint weight;
        uint date;
    }

    modifier onlyConcept() {
        require(ConceptRegistry(conceptRegistry).conceptExists(msg.sender));
        _;
    }

    function Concept(address[] _parents, uint[] _propagationRates, uint _lifetime, bytes _data) {
        require(_parents.length == _propagationRates.length);
        conceptRegistry = msg.sender;

        for (uint j=0; j < _parents.length; j++) {
            require(ConceptRegistry(conceptRegistry).conceptExists(_parents[j]));
            require(_propagationRates[j] <= 1000);
        }

        propagationRates = _propagationRates;
        parents = _parents;
        data = _data;
        lifetime = _lifetime;
        fathomToken = ConceptRegistry(conceptRegistry).fathomToken();
    }

    function getMemberLength() constant returns(uint) {
        return members.length;
    }

    function getParentsLength() constant returns(uint) {
        return parents.length;
    }

    /*
      @purpose: To add the firstUser to Mew
    */
    function addInitialMember(address _user, uint _weight) {
        if (ConceptRegistry(conceptRegistry).distributorAddress() == msg.sender)
            {
                this.addWeight(_user, _weight);
            }
    }

    /*
      @purpose: add the caller of this function to the arrays of potential assessors
      if they still have a weight in the concept
      @returns true if they are available as assessor
    */
    function setAvailability() returns(bool success){
        if (getWeight(msg.sender) > 0) {
            if (memberData[msg.sender].index == 0) {
                members.push(msg.sender);
                memberData[msg.sender].index = members.length;
                success = true;
            }
            else {
                removeMember(msg.sender);
            }
        }
   }

    /*
      //@purpose: returns a random member of the Concept or the zero address (both with approx. 50%)
      //Users with high weights are more likely to be called
      //@returns the address of the member (0x0 if there is no member)
    */
    function getWeightedRandomMember(uint seed) returns(address){
        uint weight1;
        uint weight2;
        address randomMember1;
        while (members.length > 1 && weight1 == 0) {
            uint index1 = Math.getRandom(seed, members.length - 1);
            randomMember1 = members[index1];
            weight1 = getWeight(randomMember1);
        }
        while (members.length > 1 && weight2 == 0) {
                uint index2 = Math.getRandom(seed * 2, members.length - 1);
                address randomMember2 = members[index2];
                weight2 = getWeight(randomMember2);
        }
        if (weight1 > weight2) {
            return randomMember1;
        }
    }

    /*
      @purpose: get the weight of a given member, also removes that member from the array
      if there legitimating assessment is expired
    */
    function getWeight(address _member) returns(uint weight){
        for (uint i=0; i < memberData[_member].weights.length; i++) {
            if (memberData[_member].weights[i].date > now){
                weight += memberData[_member].weights[i].weight;
            }
        }
        if (weight == 0) {
            removeMember(_member);
        }
    }
    /*
      @purpose: removes member at a given index from the members array by substituting they with
      the last member and then decreasing the size of the members array
      @returns the updated number of members in the concept
    */
    function removeMember(address _member) internal returns(uint){
        uint index = memberData[_member].index;
        if (index > 0){
            members[index] = members[members.length - 1]; //THIS NEEDS TO BE TESTED!
            memberData[_member].index = 0;
            members.length--;
        }
        return members.length;
    }

    /*
      @purpose: To make a new assessment
      @param: uint cost = the cost per assessor
      @param: uint size = the number of assessors
    */
    function makeAssessment(uint cost, uint size, uint _waitTime, uint _timeLimit) returns(bool) {
        if (size >= 5 && this.subtractBalance(msg.sender, cost*size)) {
            Assessment newAssessment = new Assessment(msg.sender, size, cost, _waitTime, _timeLimit);
            assessmentExists[address(newAssessment)] = true;
            newAssessment.setAssessorPool(block.number, address(this), size*5); //assemble the assessorPool by relevance
            return true;
        }
        else {
            return false;
        }
    }

    /*
      @purpose: To add a member to a concept and to recursively add  a member to parent concept
      @param: address assessee = the address of the assessee
      @param: uint weight = the weight for the member
      @returns: nothing
    */
    function addMember(address _assessee, uint _weight) {
        if (assessmentExists[msg.sender]) {
            memberData[_assessee].recentAssessment = msg.sender;
            memberData[_assessee].index = 0;
            this.addWeight(_assessee, _weight);
        }
    }
    function addWeight(address _assessee, uint _weight) onlyConcept() {
        if (memberData[_assessee].index == 0) {
            members.push(_assessee);
            memberData[_assessee].index = members.length;
        }

        uint idx = memberData[_assessee].componentWeightIndex[msg.sender];
        if (idx > 0) {
            memberData[_assessee].weights[idx-1] = ComponentWeight(_weight, now + lifetime);
        } else {
            memberData[_assessee].weights.push(ComponentWeight(_weight, now + lifetime));
            memberData[_assessee].componentWeightIndex[msg.sender] = memberData[_assessee].weights.length;
        }

        for(uint i = 0; i < parents.length; i++) {
            if((_weight*propagationRates[i])/1000 > 0) {
                Concept(parents[i]).addWeight(_assessee, (_weight*propagationRates[i])/1000);
            }
        }
    }

    function subtractBalance(address _from, uint _amount) returns(bool) {
        if (assessmentExists[msg.sender] || msg.sender == address(this)) {
            return FathomToken(fathomToken).subtractBalance(_from, _amount);
        }
        return false;
    }
}