contract AlchemyBase is Manager {

    // Assets of each account
    mapping (address => bytes32[8]) assets;

    // Event
    event Transfer(address from, address to);

    // Get all assets of a particular account
    function assetOf(address account) public view returns(bytes32[8]) {
        return assets[account];
    }

    function _checkAndAdd(bytes32 x, bytes32 y) internal pure returns(bytes32) {
        bytes32 mask = bytes32(255); // 0x11111111

        bytes32 result;

        uint maskedX;
        uint maskedY;
        uint maskedResult;

        for (uint i = 0; i < 31; i++) {
            // Get current mask
            if (i > 0) {
                mask = mask << 8;
            }

            // Get masked values
            maskedX = uint(x & mask);
            maskedY = uint(y & mask);
            maskedResult = maskedX + maskedY;

            // Prevent overflow
            require(maskedResult < (2 ** (8 * (i + 1))));

            // Clear result digits in masked position
            result = (result ^ mask) & result;

            // Write to result
            result = result | bytes32(maskedResult);
        }

        return result;
    }

    function _checkAndSub(bytes32 x, bytes32 y) internal pure returns(bytes32) {
        bytes32 mask = bytes32(255); // 0x11111111

        bytes32 result;

        uint maskedX;
        uint maskedY;
        uint maskedResult;

        for (uint i = 0; i < 31; i++) {
            // Get current mask
            if (i > 0) {
                mask = mask << 8;
            }

            // Get masked values
            maskedX = uint(x & mask);
            maskedY = uint(y & mask);

            // Ensure x >= y
            require(maskedX >= maskedY);

            // Calculate result
            maskedResult = maskedX - maskedY;

            // Clear result digits in masked position
            result = (result ^ mask) & result;

            // Write to result
            result = result | bytes32(maskedResult);
        }

        return result;
    }

    // Transfer assets from one account to another
    function transfer(address to, bytes32[8] value) public whenNotPaused whenTransferAllowed {
        // One can not transfer assets to self
        require(msg.sender != to);
        bytes32[8] memory assetFrom = assets[msg.sender];
        bytes32[8] memory assetTo = assets[to];

        for (uint256 i = 0; i < 8; i++) {
            assetFrom[i] = _checkAndSub(assetFrom[i], value[i]);
            assetTo[i] = _checkAndAdd(assetTo[i], value[i]);
        }

        assets[msg.sender] = assetFrom;
        assets[to] = assetTo;

        // Emit the transfer event
        emit Transfer(msg.sender, to);
    }

    // Withdraw ETH to the owner account. Ownable-->Pausable-->AlchemyBase
    function withdrawETH() external onlyCAO {
        cfo.transfer(address(this).balance);
    }
}
function assetOf(address account) public view returns(bytes32[8]) {
    return assets[account];
}

// Get all assets of a particular account