inline returns in checkOwnershi[

inline returns in checkOwnershi[

pragma solidity ^0.8.4;

import "./ERC1155Fuse.sol";
import "../interfaces/INameWrapper.sol";
import "../interfaces/IMetadataService.sol";
import "@ensdomains/ens-contracts/contracts/registry/ENS.sol";
import "@ensdomains/ens-contracts/contracts/ethregistrar/BaseRegistrar.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./BytesUtil.sol";
import "hardhat/console.sol";

contract NameWrapper is Ownable, ERC1155Fuse, INameWrapper, IERC721Receiver {
    using BytesUtils for bytes;
    ENS public immutable ens;
    BaseRegistrar public immutable registrar;
    IMetadataService public metadataService;
    mapping(bytes32 => bytes) public names;

    bytes32 private constant ETH_NODE =
        0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae;
    bytes32 private constant ROOT_NODE =
        0x0000000000000000000000000000000000000000000000000000000000000000;

    constructor(
        ENS _ens,
        BaseRegistrar _registrar,
        IMetadataService _metadataService
    ) {
        ens = _ens;
        registrar = _registrar;
        metadataService = _metadataService;

        /* Burn CANNOT_REPLACE_SUBDOMAIN and CANNOT_UNWRAP fuses for ROOT_NODE and ETH_NODE */

        _setData(
            uint256(ETH_NODE),
            address(0x0),
            uint96(CANNOT_REPLACE_SUBDOMAIN | CANNOT_UNWRAP)
        );
        _setData(
            uint256(ROOT_NODE),
            address(0x0),
            uint96(CANNOT_REPLACE_SUBDOMAIN | CANNOT_UNWRAP)
        );
        names[ROOT_NODE] = "\x00";
        names[ETH_NODE] = "\x03eth\x00";
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC1155Fuse, IERC165)
        returns (bool)
    {
        return
            interfaceId == type(INameWrapper).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /* Metadata service */

    /**
     * @notice Set the metadata service. only admin can do this
     */

    function setMetadataService(IMetadataService _newMetadataService)
        public
        onlyOwner()
    {
        metadataService = _newMetadataService;
    }

    /**
     * @notice Get the metadata uri
     * @return String uri of the metadata service
     */

    function uri(uint256 tokenId) public view override returns (string memory) {
        return metadataService.uri(tokenId);
    }

    /**
     * @notice Checks if msg.sender is the owner or approved by the owner of a name
     * @param node namehash of the name to check
     */

    modifier onlyTokenOwner(bytes32 node) {
        require(
            isTokenOwnerOrApproved(node, msg.sender),
            "NameWrapper: msg.sender is not the owner or approved"
        );
        _;
    }

    /**
     * @notice Checks if owner or approved by owner
     * @param node namehash of the name to check
     * @param addr which address to check permissions for
     * @return whether or not is owner or approved
     */

    function isTokenOwnerOrApproved(bytes32 node, address addr)
        public
        view
        override
        returns (bool)
    {
        return
            ownerOf(uint256(node)) == addr ||
            isApprovedForAll(ownerOf(uint256(node)), addr);
    }

    /**
     * @notice Gets fuse permissions for a specific name
     * @dev Fuses are represented by a uint96 where each permission is represented by 1 bit
     *      The interface has predefined fuses for all registry permissions, but additional
     *      fuses can be added for other use cases
     * @param node namehash of the name to check
     * @return fuses A number that represents the permissions a name has
     * @return vulnerability The type of vulnerability
     * @return vulnerableNode Which node is vulnerable
     */
    function getFuses(bytes32 node)
        public
        view
        override
        returns (
            uint96 fuses,
            NameSafety vulnerability,
            bytes32 vulnerableNode
        )
    {
        bytes memory name = names[node];
        require(name.length > 0, "NameWrapper: Name not found");
        (, vulnerability, vulnerableNode) = _checkHierarchy(name, 0);
        (, fuses) = getData(uint256(node));
    }

    /**
     * @notice Wraps a .eth domain, creating a new token and sending the original ERC721 token to this *         contract
     * @dev Can be called by the owner of the name in the .eth registrar or an authorised caller on the *      registrar
     * @param label label as a string of the .eth domain to wrap
     * @param _fuses initial fuses to set
     * @param wrappedOwner Owner of the name in this contract
     */

    function wrapETH2LD(
        string calldata label,
        address wrappedOwner,
        uint96 _fuses
    ) public override {
        bytes32 labelhash = _wrapETH2LD(label, wrappedOwner, _fuses);
        uint256 tokenId = uint256(labelhash);
        address owner = registrar.ownerOf(tokenId);

        require(
            owner == msg.sender ||
                isApprovedForAll(owner, msg.sender) ||
                registrar.isApprovedForAll(owner, msg.sender),
            "NameWrapper: Sender is not owner or authorised by the owner or authorised on the .eth registrar"
        );

        // transfer the token from the user to this contract
        registrar.transferFrom(owner, address(this), tokenId);
    }

    /**
     * @notice Wraps a non .eth domain, of any kind. Could be a DNSSEC name vitalik.xyz or a subdomain
     * @dev Can be called by the owner in the registry or an authorised caller in the registry
     * @param name The name to wrap, in DNS format
     * @param _fuses initial fuses to set represented as a number. Check getFuses() for more info
     * @param wrappedOwner Owner of the name in this contract
     */

    function wrap(
        bytes calldata name,
        address wrappedOwner,
        uint96 _fuses
    ) public override {
        bytes32 node = _wrap(name, wrappedOwner, _fuses);
        address owner = ens.owner(node);

        require(
            owner == msg.sender ||
                isApprovedForAll(owner, msg.sender) ||
                ens.isApprovedForAll(owner, msg.sender),
            "NameWrapper: Domain is not owned by the sender"
        );
        ens.setOwner(node, address(this));
    }

    /**
     * @notice Unwraps a .eth domain. e.g. vitalik.eth
     * @dev Can be called by the owner in the wrapper or an authorised caller in the wrapper
     * @param label label as a string of the .eth domain to wrap e.g. vitalik.xyz would be 'vitalik'
     * @param newRegistrant sets the owner in the .eth registrar to this address
     * @param newController sets the owner in the registry to this address
     */

    function unwrapETH2LD(
        bytes32 label,
        address newRegistrant,
        address newController
    ) public override onlyTokenOwner(_makeNode(ETH_NODE, label)) {
        _unwrap(_makeNode(ETH_NODE, label), newController);
        registrar.transferFrom(address(this), newRegistrant, uint256(label));
    }

    /**
     * @notice Unwraps a non .eth domain, of any kind. Could be a DNSSEC name vitalik.xyz or a subdomain
     * @dev Can be called by the owner in the wrapper or an authorised caller in the wrapper
     * @param parentNode parent namehash of the name to wrap e.g. vitalik.xyz would be namehash('xyz')
     * @param label label as a string of the .eth domain to wrap e.g. vitalik.xyz would be 'vitalik'
     * @param newController sets the owner in the registry to this address
     */

    function unwrap(
        bytes32 parentNode,
        bytes32 label,
        address newController
    ) public override onlyTokenOwner(_makeNode(parentNode, label)) {
        require(
            parentNode != ETH_NODE,
            "NameWrapper: .eth names must be unwrapped with unwrapETH2LD()"
        );
        _unwrap(_makeNode(parentNode, label), newController);
    }

    /**
     * @notice Burns any fuse passed to this function for a name
     * @dev Fuse burns are always additive and will not unburn already burnt fuses
     * @param node namehash of the name. e.g. vitalik.xyz would be namehash('vitalik.xyz')
     * @param _fuses Fuses you want to burn.
     */

    function burnFuses(bytes32 node, uint96 _fuses)
        public
        override
        onlyTokenOwner(node)
        operationAllowed(node, CANNOT_BURN_FUSES)
    {
        (address owner, uint96 fuses) = getData(uint256(node));

        uint96 newFuses = fuses | _fuses;

        _setData(uint256(node), owner, newFuses);

        emit FusesBurned(node, newFuses);
    }

    /**
     * @notice Sets records for the subdomain in the ENS Registry
     * @param parentNode namehash of the parent name
     * @param label labelhash of the subnode
     * @param owner newOwner in the registry
     * @param resolver the resolver contract in the registry
     * @param ttl ttl in the registry
     */

    function setSubnodeRecord(
        bytes32 parentNode,
        bytes32 label,
        address owner,
        address resolver,
        uint64 ttl
    )
        public
        override
        onlyTokenOwner(parentNode)
        canCallSetSubnodeOwner(parentNode, label)
    {
        ens.setSubnodeRecord(parentNode, label, owner, resolver, ttl);
    }

    /**
     * @notice Sets the subnode owner in the registry
     * @param parentNode namehash of the parent name
     * @param label labelhash of the subnode
     * @param owner newOwner in the registry
     */

    function setSubnodeOwner(
        bytes32 parentNode,
        bytes32 label,
        address owner
    )
        public
        override
        onlyTokenOwner(parentNode)
        canCallSetSubnodeOwner(parentNode, label)
        returns (bytes32)
    {
        return ens.setSubnodeOwner(parentNode, label, owner);
    }

    /**
     * @notice Sets the subdomain owner in the registry and then wraps the subdomain
     * @param parentNode parent namehash of the subdomain
     * @param label label of the subdomain as a string
     * @param newOwner newOwner in the registry
     * @param _fuses initial fuses for the wrapped subdomain
     */

    function setSubnodeOwnerAndWrap(
        bytes32 parentNode,
        string calldata label,
        address newOwner,
        uint96 _fuses
    ) public override returns (bytes32 node) {
        bytes32 labelhash = keccak256(bytes(label));
        node = setSubnodeOwner(parentNode, labelhash, address(this));
        bytes memory name = _addLabel(label, names[parentNode]);
        _wrap(name, newOwner, _fuses);
    }

    /**
     * @notice Sets the subdomain owner in the registry with records and then wraps the subdomain
     * @param parentNode parent namehash of the subdomain
     * @param label label of the subdomain as a string
     * @param newOwner newOwner in the registry
     * @param resolver resolver contract in the registry
     * @param ttl ttl in the regsitry
     * @param _fuses initial fuses for the wrapped subdomain
     */

    function setSubnodeRecordAndWrap(
        bytes32 parentNode,
        string calldata label,
        address newOwner,
        address resolver,
        uint64 ttl,
        uint96 _fuses
    ) public override {
        bytes32 labelhash = keccak256(bytes(label));
        setSubnodeRecord(parentNode, labelhash, address(this), resolver, ttl);
        bytes memory name = _addLabel(label, names[parentNode]);
        _wrap(name, newOwner, _fuses);
    }

    /**
     * @notice Sets records for the name in the ENS Registry
     * @param node namehash of the name to set a record for
     * @param owner newOwner in the registry
     * @param resolver the resolver contract
     * @param ttl ttl in the registry
     */

    function setRecord(
        bytes32 node,
        address owner,
        address resolver,
        uint64 ttl
    )
        public
        override
        onlyTokenOwner(node)
        operationAllowed(
            node,
            CANNOT_TRANSFER | CANNOT_SET_RESOLVER | CANNOT_SET_TTL
        )
    {
        ens.setRecord(node, owner, resolver, ttl);
    }

    /**
     * @notice Sets resolver contract in the registry
     * @param node namehash of the name
     * @param resolver the resolver contract
     */

    function setResolver(bytes32 node, address resolver)
        public
        override
        onlyTokenOwner(node)
        operationAllowed(node, CANNOT_SET_RESOLVER)
    {
        ens.setResolver(node, resolver);
    }

    /**
     * @notice Sets TTL in the registry
     * @param node namehash of the name
     * @param ttl TTL in the registry
     */

    function setTTL(bytes32 node, uint64 ttl)
        public
        override
        onlyTokenOwner(node)
        operationAllowed(node, CANNOT_SET_TTL)
    {
        ens.setTTL(node, ttl);
    }

    /**
     * @dev Allows an operation only if none of the specified fuses are burned.
     * @param node The namehash of the name to check fuses on.
     * @param fuseMask A bitmask of fuses that must not be burned.
     */
    modifier operationAllowed(bytes32 node, uint96 fuseMask) {
        (, uint96 fuses) = getData(uint256(node));
        require(
            fuses & fuseMask == 0,
            "NameWrapper: Operation prohibited by fuses"
        );
        _;
    }

    /**
     * @notice Check whether a name can call setSubnodeOwner/setSubnodeRecord
     * @dev Checks both canCreateSubdomain and canReplaceSubdomain and whether not they have been burnt
     *      and checks whether the owner of the subdomain is 0x0 for creating or already exists for
     *      replacing a subdomain. If either conditions are true, then it is possible to call
     *      setSubnodeOwner
     * @param node namehash of the name to check
     * @param label labelhash of the name to check
     */

    modifier canCallSetSubnodeOwner(bytes32 node, bytes32 label) {
        bytes32 subnode = _makeNode(node, label);
        address owner = ens.owner(subnode);
        (, uint96 fuses) = getData(uint256(node));

        require(
            (owner == address(0) && fuses & CANNOT_CREATE_SUBDOMAIN == 0) ||
                (owner != address(0) && fuses & CANNOT_REPLACE_SUBDOMAIN == 0),
            "NameWrapper: Operation prohibited by fuses"
        );
        _;
    }

    /**
     * @notice Checks all Fuses in the mask are burned for the node
     * @param node namehash of the name
     * @param fuseMask the fuses you want to check
     * @return Boolean of whether or not all the selected fuses are burned
     */

    function allFusesBurned(bytes32 node, uint96 fuseMask)
        public
        view
        override
        returns (bool)
    {
        (, uint96 fuses) = getData(uint256(node));
        return fuses & fuseMask == fuseMask;
    }

    function onERC721Received(
        address to,
        address,
        uint256 tokenId,
        bytes calldata data
    ) public override returns (bytes4) {
        //check if it's the eth registrar ERC721
        require(
            msg.sender == address(registrar),
            "NameWrapper: Wrapper only supports .eth ERC721 token transfers"
        );

        (string memory label, address owner, uint96 fuses) =
            abi.decode(data, (string, address, uint96));

        require(
            keccak256(bytes(label)) == bytes32(tokenId),
            "NameWrapper: Token id does match keccak(label) of label provided in data field"
        );

        _wrapETH2LD(label, owner, fuses);
        return IERC721Receiver(to).onERC721Received.selector;
    }

    /***** Internal functions */

    function _canTransfer(uint96 fuses) internal pure override returns (bool) {
        return fuses & CANNOT_TRANSFER == 0;
    }

    function _makeNode(bytes32 node, bytes32 label)
        private
        pure
        returns (bytes32)
    {
        return keccak256(abi.encodePacked(node, label));
    }

    function _addLabel(string memory label, bytes memory name)
        internal
        pure
        returns (bytes memory ret)
    {
        require(bytes(label).length < 256, "NameWrapper: Label too long");
        return abi.encodePacked(uint8(bytes(label).length), label, name);
    }

    function _mint(
        bytes32 node,
        bytes memory name,
        address wrappedOwner,
        uint96 _fuses
    ) internal {
        names[node] = name;

        address oldWrappedOwner = ownerOf(uint256(node));
        if (oldWrappedOwner != address(0)) {
            // burn and unwrap old token of old owner
            _burn(uint256(node));
            emit NameUnwrapped(node, address(0));
        }
        _mint(node, wrappedOwner, _fuses);
    }

    function _wrap(
        bytes memory name,
        address wrappedOwner,
        uint96 _fuses
    ) private returns (bytes32 node) {
        (bytes32 labelhash, uint256 offset) = name.readLabel(0);
        bytes32 parentNode = name.namehash(offset);

        require(
            parentNode != ETH_NODE,
            "NameWrapper: .eth domains need to use wrapETH2LD()"
        );

        node = _makeNode(parentNode, labelhash);

        _mint(node, name, wrappedOwner, _fuses);
        emit NameWrapped(node, name, wrappedOwner, _fuses);
    }

    function _wrapETH2LD(
        string memory label,
        address wrappedOwner,
        uint96 _fuses
    ) private returns (bytes32 labelhash) {
        labelhash = keccak256(bytes(label));
        bytes32 node = _makeNode(ETH_NODE, labelhash);

        // transfer the ens record back to the new owner (this contract)
        registrar.reclaim(uint256(labelhash), address(this));

        // mint a new ERC1155 token with fuses
        bytes memory name = _addLabel(label, "\x03eth\x00");
        _mint(node, name, wrappedOwner, _fuses);

        emit NameWrapped(node, name, wrappedOwner, _fuses);
    }

    function _unwrap(bytes32 node, address newOwner) private {
        require(
            newOwner != address(0x0),
            "NameWrapper: Target owner cannot be 0x0"
        );
        require(
            newOwner != address(this),
            "NameWrapper: Target owner cannot be the NameWrapper contract"
        );
        require(
            !allFusesBurned(node, CANNOT_UNWRAP),
            "NameWrapper: Domain is not unwrappable"
        );

        // burn token and fuse data
        _burn(uint256(node));
        ens.setOwner(node, newOwner);

        emit NameUnwrapped(node, newOwner);
    }

    function _setData(
        uint256 tokenId,
        address owner,
        uint96 fuses
    ) internal override {
        require(
            fuses == CAN_DO_EVERYTHING || fuses & CANNOT_UNWRAP != 0,
            "NameWrapper: Cannot burn fuses: domain can be unwrapped"
        );
        super._setData(tokenId, owner, fuses);
    }

    /**
     * @dev Internal function that checks all a name's ancestors to ensure fuse values will be respected and parent controller/registrant are set to the Wrapper
     * @param name The name to check.
     * @param offset The offset into the name to start at.
     * @return node The calculated namehash for this part of the name.
     * @return vulnerability what kind of vulnerability the node has
     * @return vulnerableNode which node is at risk
     */
    function _checkHierarchy(bytes memory name, uint256 offset)
        internal
        view
        returns (
            bytes32 node,
            NameSafety vulnerability,
            bytes32 vulnerableNode
        )
    {
        // Read the first label. If it's the root, return immediately.
        (bytes32 labelhash, uint256 newOffset) = name.readLabel(offset);
        if (labelhash == bytes32(0)) {
            // Root node
            return (bytes32(0), NameSafety.Safe, 0);
        }

        // Check the parent name
        bytes32 parentNode;
        (parentNode, vulnerability, vulnerableNode) = _checkHierarchy(
            name,
            newOffset
        );

        node = _makeNode(parentNode, labelhash);

        // stop function checking any other nodes if a parent is not safe
        if (vulnerability != NameSafety.Safe) {
            return (node, vulnerability, vulnerableNode);
        }

        // Check the parent name's fuses to see if replacing subdomains is forbidden
        if (parentNode == ROOT_NODE) {
            // Save ourselves some gas; root node can't be replaced
            return (node, NameSafety.Safe, 0);
        }

        (vulnerability, vulnerableNode) = _checkOwnership(
            labelhash,
            node,
            parentNode
        );

        if (vulnerability != NameSafety.Safe) {
            return (node, vulnerability, vulnerableNode);
        }

        if (!allFusesBurned(parentNode, CANNOT_REPLACE_SUBDOMAIN)) {
            return (node, NameSafety.SubdomainReplacementAllowed, parentNode);
        }

        return (node, NameSafety.Safe, 0);
    }

    function _checkOwnership(
        bytes32 labelhash,
        bytes32 node,
        bytes32 parentNode
    ) internal view returns (NameSafety vulnerability, bytes32 vulnerableNode) {
        if (parentNode == ETH_NODE) {
            // Special case .eth: Check registrant or name isexpired

            try registrar.ownerOf(uint256(labelhash)) returns (
                address registrarOwner
            ) {
                if (registrarOwner != address(this)) {
                    return (NameSafety.RegistrantNotWrapped, node);
                }
            } catch {
                return (NameSafety.Expired, node);
            }
        }

        if (ens.owner(node) != address(this)) {
            return (NameSafety.ControllerNotWrapped, node);
        }
    }
}

pragma solidity ^0.8.4;

import "./ERC1155Fuse.sol";
import "../interfaces/INameWrapper.sol";
import "../interfaces/IMetadataService.sol";
import "@ensdomains/ens-contracts/contracts/registry/ENS.sol";
import "@ensdomains/ens-contracts/contracts/ethregistrar/BaseRegistrar.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./BytesUtil.sol";
import "hardhat/console.sol";

contract NameWrapper is Ownable, ERC1155Fuse, INameWrapper, IERC721Receiver {
    using BytesUtils for bytes;
    ENS public immutable ens;
    BaseRegistrar public immutable registrar;
    IMetadataService public metadataService;
    mapping(bytes32 => bytes) public names;

    bytes32 private constant ETH_NODE =
        0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae;
    bytes32 private constant ROOT_NODE =
        0x0000000000000000000000000000000000000000000000000000000000000000;

    constructor(
        ENS _ens,
        BaseRegistrar _registrar,
        IMetadataService _metadataService
    ) {
        ens = _ens;
        registrar = _registrar;
        metadataService = _metadataService;

        /* Burn CANNOT_REPLACE_SUBDOMAIN and CANNOT_UNWRAP fuses for ROOT_NODE and ETH_NODE */

        _setData(
            uint256(ETH_NODE),
            address(0x0),
            uint96(CANNOT_REPLACE_SUBDOMAIN | CANNOT_UNWRAP)
        );
        _setData(
            uint256(ROOT_NODE),
            address(0x0),
            uint96(CANNOT_REPLACE_SUBDOMAIN | CANNOT_UNWRAP)
        );
        names[ROOT_NODE] = "\x00";
        names[ETH_NODE] = "\x03eth\x00";
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC1155Fuse, IERC165)
        returns (bool)
    {
        return
            interfaceId == type(INameWrapper).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /* Metadata service */

    /**
     * @notice Set the metadata service. only admin can do this
     */

    function setMetadataService(IMetadataService _newMetadataService)
        public
        onlyOwner()
    {
        metadataService = _newMetadataService;
    }

    /**
     * @notice Get the metadata uri
     * @return String uri of the metadata service
     */

    function uri(uint256 tokenId) public view override returns (string memory) {
        return metadataService.uri(tokenId);
    }

    /**
     * @notice Checks if msg.sender is the owner or approved by the owner of a name
     * @param node namehash of the name to check
     */

    modifier onlyTokenOwner(bytes32 node) {
        require(
            isTokenOwnerOrApproved(node, msg.sender),
            "NameWrapper: msg.sender is not the owner or approved"
        );
        _;
    }

    /**
     * @notice Checks if owner or approved by owner
     * @param node namehash of the name to check
     * @param addr which address to check permissions for
     * @return whether or not is owner or approved
     */

    function isTokenOwnerOrApproved(bytes32 node, address addr)
        public
        view
        override
        returns (bool)
    {
        return
            ownerOf(uint256(node)) == addr ||
            isApprovedForAll(ownerOf(uint256(node)), addr);
    }

    /**
     * @notice Gets fuse permissions for a specific name
     * @dev Fuses are represented by a uint96 where each permission is represented by 1 bit
     *      The interface has predefined fuses for all registry permissions, but additional
     *      fuses can be added for other use cases
     * @param node namehash of the name to check
     * @return fuses A number that represents the permissions a name has
     * @return vulnerability The type of vulnerability
     * @return vulnerableNode Which node is vulnerable
     */
    function getFuses(bytes32 node)
        public
        view
        override
        returns (
            uint96 fuses,
            NameSafety vulnerability,
            bytes32 vulnerableNode
        )
    {
        bytes memory name = names[node];
        require(name.length > 0, "NameWrapper: Name not found");
        (, vulnerability, vulnerableNode) = _checkHierarchy(name, 0);
        (, fuses) = getData(uint256(node));
    }

    /**
     * @notice Wraps a .eth domain, creating a new token and sending the original ERC721 token to this *         contract
     * @dev Can be called by the owner of the name in the .eth registrar or an authorised caller on the *      registrar
     * @param label label as a string of the .eth domain to wrap
     * @param _fuses initial fuses to set
     * @param wrappedOwner Owner of the name in this contract
     */

    function wrapETH2LD(
        string calldata label,
        address wrappedOwner,
        uint96 _fuses
    ) public override {
        bytes32 labelhash = _wrapETH2LD(label, wrappedOwner, _fuses);
        uint256 tokenId = uint256(labelhash);
        address owner = registrar.ownerOf(tokenId);

        require(
            owner == msg.sender ||
                isApprovedForAll(owner, msg.sender) ||
                registrar.isApprovedForAll(owner, msg.sender),
            "NameWrapper: Sender is not owner or authorised by the owner or authorised on the .eth registrar"
        );

        // transfer the token from the user to this contract
        registrar.transferFrom(owner, address(this), tokenId);
    }

    /**
     * @notice Wraps a non .eth domain, of any kind. Could be a DNSSEC name vitalik.xyz or a subdomain
     * @dev Can be called by the owner in the registry or an authorised caller in the registry
     * @param name The name to wrap, in DNS format
     * @param _fuses initial fuses to set represented as a number. Check getFuses() for more info
     * @param wrappedOwner Owner of the name in this contract
     */

    function wrap(
        bytes calldata name,
        address wrappedOwner,
        uint96 _fuses
    ) public override {
        bytes32 node = _wrap(name, wrappedOwner, _fuses);
        address owner = ens.owner(node);

        require(
            owner == msg.sender ||
                isApprovedForAll(owner, msg.sender) ||
                ens.isApprovedForAll(owner, msg.sender),
            "NameWrapper: Domain is not owned by the sender"
        );
        ens.setOwner(node, address(this));
    }

    /**
     * @notice Unwraps a .eth domain. e.g. vitalik.eth
     * @dev Can be called by the owner in the wrapper or an authorised caller in the wrapper
     * @param label label as a string of the .eth domain to wrap e.g. vitalik.xyz would be 'vitalik'
     * @param newRegistrant sets the owner in the .eth registrar to this address
     * @param newController sets the owner in the registry to this address
     */

    function unwrapETH2LD(
        bytes32 label,
        address newRegistrant,
        address newController
    ) public override onlyTokenOwner(_makeNode(ETH_NODE, label)) {
        _unwrap(_makeNode(ETH_NODE, label), newController);
        registrar.transferFrom(address(this), newRegistrant, uint256(label));
    }

    /**
     * @notice Unwraps a non .eth domain, of any kind. Could be a DNSSEC name vitalik.xyz or a subdomain
     * @dev Can be called by the owner in the wrapper or an authorised caller in the wrapper
     * @param parentNode parent namehash of the name to wrap e.g. vitalik.xyz would be namehash('xyz')
     * @param label label as a string of the .eth domain to wrap e.g. vitalik.xyz would be 'vitalik'
     * @param newController sets the owner in the registry to this address
     */

    function unwrap(
        bytes32 parentNode,
        bytes32 label,
        address newController
    ) public override onlyTokenOwner(_makeNode(parentNode, label)) {
        require(
            parentNode != ETH_NODE,
            "NameWrapper: .eth names must be unwrapped with unwrapETH2LD()"
        );
        _unwrap(_makeNode(parentNode, label), newController);
    }

    /**
     * @notice Burns any fuse passed to this function for a name
     * @dev Fuse burns are always additive and will not unburn already burnt fuses
     * @param node namehash of the name. e.g. vitalik.xyz would be namehash('vitalik.xyz')
     * @param _fuses Fuses you want to burn.
     */

    function burnFuses(bytes32 node, uint96 _fuses)
        public
        override
        onlyTokenOwner(node)
        operationAllowed(node, CANNOT_BURN_FUSES)
    {
        (address owner, uint96 fuses) = getData(uint256(node));

        uint96 newFuses = fuses | _fuses;

        _setData(uint256(node), owner, newFuses);

        emit FusesBurned(node, newFuses);
    }

    /**
     * @notice Sets records for the subdomain in the ENS Registry
     * @param parentNode namehash of the parent name
     * @param label labelhash of the subnode
     * @param owner newOwner in the registry
     * @param resolver the resolver contract in the registry
     * @param ttl ttl in the registry
     */

    function setSubnodeRecord(
        bytes32 parentNode,
        bytes32 label,
        address owner,
        address resolver,
        uint64 ttl
    )
        public
        override
        onlyTokenOwner(parentNode)
        canCallSetSubnodeOwner(parentNode, label)
    {
        ens.setSubnodeRecord(parentNode, label, owner, resolver, ttl);
    }

    /**
     * @notice Sets the subnode owner in the registry
     * @param parentNode namehash of the parent name
     * @param label labelhash of the subnode
     * @param owner newOwner in the registry
     */

    function setSubnodeOwner(
        bytes32 parentNode,
        bytes32 label,
        address owner
    )
        public
        override
        onlyTokenOwner(parentNode)
        canCallSetSubnodeOwner(parentNode, label)
        returns (bytes32)
    {
        return ens.setSubnodeOwner(parentNode, label, owner);
    }

    /**
     * @notice Sets the subdomain owner in the registry and then wraps the subdomain
     * @param parentNode parent namehash of the subdomain
     * @param label label of the subdomain as a string
     * @param newOwner newOwner in the registry
     * @param _fuses initial fuses for the wrapped subdomain
     */

    function setSubnodeOwnerAndWrap(
        bytes32 parentNode,
        string calldata label,
        address newOwner,
        uint96 _fuses
    ) public override returns (bytes32 node) {
        bytes32 labelhash = keccak256(bytes(label));
        node = setSubnodeOwner(parentNode, labelhash, address(this));
        bytes memory name = _addLabel(label, names[parentNode]);
        _wrap(name, newOwner, _fuses);
    }

    /**
     * @notice Sets the subdomain owner in the registry with records and then wraps the subdomain
     * @param parentNode parent namehash of the subdomain
     * @param label label of the subdomain as a string
     * @param newOwner newOwner in the registry
     * @param resolver resolver contract in the registry
     * @param ttl ttl in the regsitry
     * @param _fuses initial fuses for the wrapped subdomain
     */

    function setSubnodeRecordAndWrap(
        bytes32 parentNode,
        string calldata label,
        address newOwner,
        address resolver,
        uint64 ttl,
        uint96 _fuses
    ) public override {
        bytes32 labelhash = keccak256(bytes(label));
        setSubnodeRecord(parentNode, labelhash, address(this), resolver, ttl);
        bytes memory name = _addLabel(label, names[parentNode]);
        _wrap(name, newOwner, _fuses);
    }

    /**
     * @notice Sets records for the name in the ENS Registry
     * @param node namehash of the name to set a record for
     * @param owner newOwner in the registry
     * @param resolver the resolver contract
     * @param ttl ttl in the registry
     */

    function setRecord(
        bytes32 node,
        address owner,
        address resolver,
        uint64 ttl
    )
        public
        override
        onlyTokenOwner(node)
        operationAllowed(
            node,
            CANNOT_TRANSFER | CANNOT_SET_RESOLVER | CANNOT_SET_TTL
        )
    {
        ens.setRecord(node, owner, resolver, ttl);
    }

    /**
     * @notice Sets resolver contract in the registry
     * @param node namehash of the name
     * @param resolver the resolver contract
     */

    function setResolver(bytes32 node, address resolver)
        public
        override
        onlyTokenOwner(node)
        operationAllowed(node, CANNOT_SET_RESOLVER)
    {
        ens.setResolver(node, resolver);
    }

    /**
     * @notice Sets TTL in the registry
     * @param node namehash of the name
     * @param ttl TTL in the registry
     */

    function setTTL(bytes32 node, uint64 ttl)
        public
        override
        onlyTokenOwner(node)
        operationAllowed(node, CANNOT_SET_TTL)
    {
        ens.setTTL(node, ttl);
    }

    /**
     * @dev Allows an operation only if none of the specified fuses are burned.
     * @param node The namehash of the name to check fuses on.
     * @param fuseMask A bitmask of fuses that must not be burned.
     */
    modifier operationAllowed(bytes32 node, uint96 fuseMask) {
        (, uint96 fuses) = getData(uint256(node));
        require(
            fuses & fuseMask == 0,
            "NameWrapper: Operation prohibited by fuses"
        );
        _;
    }

    /**
     * @notice Check whether a name can call setSubnodeOwner/setSubnodeRecord
     * @dev Checks both canCreateSubdomain and canReplaceSubdomain and whether not they have been burnt
     *      and checks whether the owner of the subdomain is 0x0 for creating or already exists for
     *      replacing a subdomain. If either conditions are true, then it is possible to call
     *      setSubnodeOwner
     * @param node namehash of the name to check
     * @param label labelhash of the name to check
     */

    modifier canCallSetSubnodeOwner(bytes32 node, bytes32 label) {
        bytes32 subnode = _makeNode(node, label);
        address owner = ens.owner(subnode);
        (, uint96 fuses) = getData(uint256(node));

        require(
            (owner == address(0) && fuses & CANNOT_CREATE_SUBDOMAIN == 0) ||
                (owner != address(0) && fuses & CANNOT_REPLACE_SUBDOMAIN == 0),
            "NameWrapper: Operation prohibited by fuses"
        );
        _;
    }

    /**
     * @notice Checks all Fuses in the mask are burned for the node
     * @param node namehash of the name
     * @param fuseMask the fuses you want to check
     * @return Boolean of whether or not all the selected fuses are burned
     */

    function allFusesBurned(bytes32 node, uint96 fuseMask)
        public
        view
        override
        returns (bool)
    {
        (, uint96 fuses) = getData(uint256(node));
        return fuses & fuseMask == fuseMask;
    }

    function onERC721Received(
        address to,
        address,
        uint256 tokenId,
        bytes calldata data
    ) public override returns (bytes4) {
        //check if it's the eth registrar ERC721
        require(
            msg.sender == address(registrar),
            "NameWrapper: Wrapper only supports .eth ERC721 token transfers"
        );

        (string memory label, address owner, uint96 fuses) =
            abi.decode(data, (string, address, uint96));

        require(
            keccak256(bytes(label)) == bytes32(tokenId),
            "NameWrapper: Token id does match keccak(label) of label provided in data field"
        );

        _wrapETH2LD(label, owner, fuses);
        return IERC721Receiver(to).onERC721Received.selector;
    }

    /***** Internal functions */

    function _canTransfer(uint96 fuses) internal pure override returns (bool) {
        return fuses & CANNOT_TRANSFER == 0;
    }

    function _makeNode(bytes32 node, bytes32 label)
        private
        pure
        returns (bytes32)
    {
        return keccak256(abi.encodePacked(node, label));
    }

    function _addLabel(string memory label, bytes memory name)
        internal
        pure
        returns (bytes memory ret)
    {
        require(bytes(label).length < 256, "NameWrapper: Label too long");
        return abi.encodePacked(uint8(bytes(label).length), label, name);
    }

    function _mint(
        bytes32 node,
        bytes memory name,
        address wrappedOwner,
        uint96 _fuses
    ) internal {
        names[node] = name;

        address oldWrappedOwner = ownerOf(uint256(node));
        if (oldWrappedOwner != address(0)) {
            // burn and unwrap old token of old owner
            _burn(uint256(node));
            emit NameUnwrapped(node, address(0));
        }
        _mint(node, wrappedOwner, _fuses);
    }

    function _wrap(
        bytes memory name,
        address wrappedOwner,
        uint96 _fuses
    ) private returns (bytes32 node) {
        (bytes32 labelhash, uint256 offset) = name.readLabel(0);
        bytes32 parentNode = name.namehash(offset);

        require(
            parentNode != ETH_NODE,
            "NameWrapper: .eth domains need to use wrapETH2LD()"
        );

        node = _makeNode(parentNode, labelhash);

        _mint(node, name, wrappedOwner, _fuses);
        emit NameWrapped(node, name, wrappedOwner, _fuses);
    }

    function _wrapETH2LD(
        string memory label,
        address wrappedOwner,
        uint96 _fuses
    ) private returns (bytes32 labelhash) {
        labelhash = keccak256(bytes(label));
        bytes32 node = _makeNode(ETH_NODE, labelhash);

        // transfer the ens record back to the new owner (this contract)
        registrar.reclaim(uint256(labelhash), address(this));

        // mint a new ERC1155 token with fuses
        bytes memory name = _addLabel(label, "\x03eth\x00");
        _mint(node, name, wrappedOwner, _fuses);

        emit NameWrapped(node, name, wrappedOwner, _fuses);
    }

    function _unwrap(bytes32 node, address newOwner) private {
        require(
            newOwner != address(0x0),
            "NameWrapper: Target owner cannot be 0x0"
        );
        require(
            newOwner != address(this),
            "NameWrapper: Target owner cannot be the NameWrapper contract"
        );
        require(
            !allFusesBurned(node, CANNOT_UNWRAP),
            "NameWrapper: Domain is not unwrappable"
        );

        // burn token and fuse data
        _burn(uint256(node));
        ens.setOwner(node, newOwner);

        emit NameUnwrapped(node, newOwner);
    }

    function _setData(
        uint256 tokenId,
        address owner,
        uint96 fuses
    ) internal override {
        require(
            fuses == CAN_DO_EVERYTHING || fuses & CANNOT_UNWRAP != 0,
            "NameWrapper: Cannot burn fuses: domain can be unwrapped"
        );
        super._setData(tokenId, owner, fuses);
    }

    /**
     * @dev Internal function that checks all a name's ancestors to ensure fuse values will be respected and parent controller/registrant are set to the Wrapper
     * @param name The name to check.
     * @param offset The offset into the name to start at.
     * @return node The calculated namehash for this part of the name.
     * @return vulnerability what kind of vulnerability the node has
     * @return vulnerableNode which node is at risk
     */
    function _checkHierarchy(bytes memory name, uint256 offset)
        internal
        view
        returns (
            bytes32 node,
            NameSafety vulnerability,
            bytes32 vulnerableNode
        )
    {
        // Read the first label. If it's the root, return immediately.
        (bytes32 labelhash, uint256 newOffset) = name.readLabel(offset);
        if (labelhash == bytes32(0)) {
            // Root node
            return (bytes32(0), NameSafety.Safe, 0);
        }

        // Check the parent name
        bytes32 parentNode;
        (parentNode, vulnerability, vulnerableNode) = _checkHierarchy(
            name,
            newOffset
        );

        node = _makeNode(parentNode, labelhash);

        // stop function checking any other nodes if a parent is not safe
        if (vulnerability != NameSafety.Safe) {
            return (node, vulnerability, vulnerableNode);
        }

        // Check the parent name's fuses to see if replacing subdomains is forbidden
        if (parentNode == ROOT_NODE) {
            // Save ourselves some gas; root node can't be replaced
            return (node, NameSafety.Safe, 0);
        }

        (vulnerability, vulnerableNode) = _checkOwnership(
            labelhash,
            node,
            parentNode
        );

        if (vulnerability != NameSafety.Safe) {
            return (node, vulnerability, vulnerableNode);
        }

        if (!allFusesBurned(parentNode, CANNOT_REPLACE_SUBDOMAIN)) {
            return (node, NameSafety.SubdomainReplacementAllowed, parentNode);
        }

        return (node, NameSafety.Safe, 0);
    }

    function _checkOwnership(
        bytes32 labelhash,
        bytes32 node,
        bytes32 parentNode
    ) internal view returns (NameSafety vulnerability, bytes32 vulnerableNode) {
        if (parentNode == ETH_NODE) {
            // Special case .eth: Check registrant or name isexpired

            try registrar.ownerOf(uint256(labelhash)) returns (
                address registrarOwner
            ) {
                if (registrarOwner != address(this)) {
                    vulnerability = NameSafety.RegistrantNotWrapped;
                    vulnerableNode = node;
                    return (vulnerability, vulnerableNode);
                }
            } catch {
                vulnerability = NameSafety.Expired;
                vulnerableNode = node;
                return (vulnerability, vulnerableNode);
            }
        }

        if (ens.owner(node) != address(this)) {
            vulnerability = NameSafety.ControllerNotWrapped;
            vulnerableNode = node;
            return (vulnerability, vulnerableNode);
        }
    }
}


Add baseUnitForBtcVolume

Add baseUnitForBtcVolume

contract coin {}

contract issuer {
    address public issuerAddr;
    address public coinAddr;
    coin public pluton;
    uint dayBtcVolume;
    uint volumeUpdateTimestamp;

    struct Rebate {
        uint plutonRewardRate;
        uint maxPlutonRewardRate;
        uint minPlutonRewardRate;
        uint minDayVolumeForReduce;
        uint dayRebateRateChange;
        uint plutonRewardRateReduceStep;
        uint plutonRewardRateReduce;
        uint baseUnitForRebate;
        uint baseUnitForBtcVolume;
    }

    Rebate public rebate;

    modifier ownerCheck { if (msg.sender == issuerAddr) _ }

    /*Initial */
    function issuer(address _issuer, coin _plutonAddr) {
        issuerAddr = _issuer;
        coinAddr = _plutonAddr;

        rebate.baseUnitForRebate = 1000; // accrual 0,1%
        rebate.maxPlutonRewardRate = 30; // 3%
        rebate.plutonRewardRate = rebate.maxPlutonRewardRate; // 3%
        rebate.minPlutonRewardRate = 10; // 1%
        rebate.minDayVolumeForReduce = 50; // 5 BTC
        rebate.plutonRewardRateReduce = 1; // reduce 0,1% from every 0.1 BTC
        rebate.plutonRewardRateReduceStep = 1; // reduce step 0.1 BTC
        rebate.dayRebateRateChange = 0; // Initial data
        rebate.baseUnitForBtcVolume = 10; // accrual 0,1 BTC

        dayBtcVolume = 0;
        volumeUpdateTimestamp = now;

        pluton = coin(_plutonAddr);
    }

    /* issuer functions */
    /* _lastDayBtcVolume need multiply 10 */
    function updRebateRate(uint _lastDayBtcVolume) ownerCheck returns(uint plutonRewardRate) {
        if(_lastDayBtcVolume > dayBtcVolume)
        {
            rebate.dayRebateRateChange = (_lastDayBtcVolume - dayBtcVolume) / rebate.plutonRewardRateReduceStep * rebate.plutonRewardRateReduce;
            if(rebate.plutonRewardRate - rebate.dayRebateRateChange <= rebate.minPlutonRewardRate) {rebate.plutonRewardRate = rebate.minPlutonRewardRate; dayBtcVolume = _lastDayBtcVolume;}
                else {rebate.plutonRewardRate = (rebate.plutonRewardRate - rebate.dayRebateRateChange) / rebate.baseUnitForBtcVolume;  dayBtcVolume = _lastDayBtcVolume;}
        } else {
            rebate.dayRebateRateChange = (dayBtcVolume - _lastDayBtcVolume) / rebate.plutonRewardRateReduceStep * rebate.plutonRewardRateReduce;
            if(rebate.dayRebateRateChange + rebate.plutonRewardRate >= rebate.maxPlutonRewardRate) {rebate.plutonRewardRate = rebate.maxPlutonRewardRate;  dayBtcVolume = _lastDayBtcVolume;}
                else {rebate.plutonRewardRate = (rebate.plutonRewardRate + rebate.dayRebateRateChange) / rebate.baseUnitForBtcVolume;  dayBtcVolume = _lastDayBtcVolume;}
        }

        return(rebate.plutonRewardRate);
    }

    function getRebate() ownerCheck returns(uint plutonReward) {
        return(rebate.plutonRewardRate);
         //   pluton.emmision(plutonReward);
        //    pluton.transfer(plutonReward, _btcSeller);
    }

}

contract coin {}

contract issuer {
    address public issuerAddr;
    address public coinAddr;
    coin public pluton;
    uint dayBtcVolume;
    uint volumeUpdateTimestamp;

    struct Rebate {
        uint plutonRewardRate;
        uint maxPlutonRewardRate;
        uint minPlutonRewardRate;
        uint minDayVolumeForReduce;
        uint dayRebateRateChange;
        uint plutonRewardRateReduceStep;
        uint plutonRewardRateReduce;
        uint baseUnitForRebate;
    }
    Rebate public rebate;

    modifier ownerCheck { if (msg.sender == issuerAddr) _ }

    /*Initial */
    function issuer(address _issuer, coin _plutonAddr) {
        issuerAddr = _issuer;
        coinAddr = _plutonAddr;

        rebate.baseUnitForRebate = 1000; // accrual 0,1%
        rebate.maxPlutonRewardRate = 30; // 3%
        rebate.plutonRewardRate = rebate.maxPlutonRewardRate; // 3%
        rebate.minPlutonRewardRate = 10; // 1%
        rebate.minDayVolumeForReduce = 500; // 500 BTC
        rebate.plutonRewardRateReduce = 1; // reduce 0,1% from every 100 BTC
        rebate.plutonRewardRateReduceStep = 100; // reduce step 100 BTC
        rebate.dayRebateRateChange = 0; // Initial data

        dayBtcVolume = 0;
        volumeUpdateTimestamp = now;

        pluton = coin(_plutonAddr);
    }

    /* issuer functions */

    function updRebateRate(uint _lastDayBtcVolume) returns(uint plutonRewardRate) {
        if(_lastDayBtcVolume > dayBtcVolume)
        {
            rebate.dayRebateRateChange = (_lastDayBtcVolume - dayBtcVolume) / rebate.plutonRewardRateReduceStep * rebate.plutonRewardRateReduce;
            if(rebate.plutonRewardRate - rebate.dayRebateRateChange <= rebate.minPlutonRewardRate) {rebate.plutonRewardRate = rebate.minPlutonRewardRate; dayBtcVolume = _lastDayBtcVolume;}
                else {rebate.plutonRewardRate = rebate.plutonRewardRate - rebate.dayRebateRateChange;  dayBtcVolume = _lastDayBtcVolume;}
        } else {
            rebate.dayRebateRateChange = (dayBtcVolume - _lastDayBtcVolume) / rebate.plutonRewardRateReduceStep * rebate.plutonRewardRateReduce;
            if(rebate.dayRebateRateChange + rebate.plutonRewardRate >= rebate.maxPlutonRewardRate) {rebate.plutonRewardRate = rebate.maxPlutonRewardRate;  dayBtcVolume = _lastDayBtcVolume;}
                else {rebate.plutonRewardRate = rebate.plutonRewardRate + rebate.dayRebateRateChange;  dayBtcVolume = _lastDayBtcVolume;}
        }

        return(rebate.plutonRewardRate);

    }

    function getRebate() ownerCheck returns(uint plutonReward) {
        return(rebate.plutonRewardRate);
         //   pluton.emmision(plutonReward);
        //    pluton.transfer(plutonReward, _btcSeller);
    }

}


new function add friend. change to public friends attribute

pragma solidity ^0.4.5;

contract Splitter {

    uint public balance;

    address[] public friends;

    address public owner;

    event LogAddFriendEvent(address main, address friend);

    event LogFailSendEvent(address main, address friend, uint value, uint total);

    event LogSendEvent(address main, address friend, uint value, uint total);

    modifier isOwner {
        if (msg.sender != owner) {
            revert();
        }
        _;
    }

    function Splitter(address[] addresses) public {

        if(addresses.length == 0) revert();

        for(uint i=0; i<addresses.length; i++){
            if(addresses[i] == msg.sender) revert();
        }
        owner = msg.sender;
        friends = addresses;
    }

    function addFriend(address newFriend) isOwner public {

        for(uint i=0; i<friends.length; i++){
            if(friends[i] == newFriend) revert();
        }

        friends.push(newFriend);
        LogAddFriendEvent(msg.sender, newFriend);

    }

    function split() payable isOwner public returns (bool fail) {

        fail = false;
        uint moneyToSent = msg.value / friends.length;
        uint totalSent;
        for(uint i=0; i<friends.length; i++){
            if(!friends[i].send(moneyToSent)){
                LogFailSendEvent(owner, friends[i], moneyToSent, msg.value);
                fail = true;
            }else{
                totalSent += moneyToSent;
                LogSendEvent(owner, friends[i], moneyToSent, msg.value);
            }
        }
        balance = totalSent;

    }

  function kill() isOwner public {
        selfdestruct(msg.sender);
  }

}

pragma solidity ^0.4.5;

contract Splitter {

    uint public balance;

    address[] private friends;

    address public owner;

    event LogFailSendEvent(address main, address friend, uint value, uint total);

    event LogSendEvent(address main, address friend, uint value, uint total);

    modifier isOwner {
        if (msg.sender != owner) {
            revert();
        }
        _;
    }

    function Splitter(address[] addresses) public {

        if(addresses.length == 0) revert();

        for(uint i=0; i<addresses.length; i++){
            if(addresses[i] == msg.sender) revert();
        }
        owner = msg.sender;
        friends = addresses;
    }

    function split() payable isOwner public returns (bool fail) {

        fail = false;
        uint moneyToSent = msg.value / friends.length;
        uint totalSent;
        for(uint i=0; i<friends.length; i++){
            if(!friends[i].send(moneyToSent)){
                LogFailSendEvent(owner, friends[i], moneyToSent, msg.value);
                fail = true;
            }else{
                totalSent += moneyToSent;
                LogSendEvent(owner, friends[i], moneyToSent, msg.value);
            }
        }
        balance = totalSent;

    }

  function kill() isOwner public {
        selfdestruct(msg.sender);
  }

}


deliberate syntax error for test

deliberate syntax error for test

deliberate-syntax-error-for-test - 3828, x
rrr
/// Partnership
/// Requires all pre-defined partners agreement on transactions and operations.
contract Partnership
{
	event Funded();
	event Deposit(address _from, uint _value);
	event TransactionProposed(bytes32 _id, address _initiator, string _description);
	event TransactionPassed(bytes32 _id, address _finalSigner, string _description);
	event TransactionSent(bytes32 _transaction, address _executor, string _description);
	event Withdrawal(address _partner, uint _amount);

	/// Price in wei of each equal share of the partnership
	uint public sharePrice;

	/// Flag indicating whether or not all partners have paid for their share
	bool public funded;

	/// Array of partner addresses
	address [] public partners;

	/// Collection of partner records
	mapping(address => Partner) public partnerRecords;

	/// Count of partners
	uint public partnerCount;

	/// Count of partners who have paid for their share
	uint public paidPartnerCount;

	/// Collection of pending transactions (ie send X ETH to Y with Z data)
	mapping(bytes32 => Transaction) public transactions;

	struct Partner {
		/// Flag indicating that this record has been initialized
		bool isPartner;
		/// Flag indicating that the partner has paid for their share
		bool paid;
		/// Total amount loaned to the partnership by the partner
		uint loanBalance;
		/// Amount released for withdrawal by the partner
		uint withdrawableAmount;
	}

	struct Transaction {
		/// Flag indicating that this record has been initialized
		bool valid;
		/// Proposed recipient for the transaction (0 indicates a new contract will be created)
		address to;
		/// Proposed amount to send (0 indicates no wei)
		uint value;
		/// Optional array of data to send with the transaction
		bytes data;
		/// Optional description of proposed transaction
		string description;
		/// Account that created the transaction
		address creator;
		/// Total number of partners that have confirmed/voted
		uint voteCount;
		/// Collection of partners that have confirmed/voted
		mapping(address => uint) votes;
		/// Flag indicating that all partners have confirmed
		bool passed;
		/// Flag indicatint that the transaction has been sent
		bool sent;
	}

	modifier onlyFunded {
		if (!funded)
	       		throw;
		_
	}

	modifier onlyPartner {
		if (!isPartner(msg.sender))
			throw;
		_
	}

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

	function Partnership(address[] _partners, uint _sharePrice) {
		funded = false;
		partners = _partners;
		sharePrice = _sharePrice;
		for (uint i = 0; i < _partners.length; i++) {
			partnerRecords[_partners[i]].isPartner = true;
		}
		partnerCount = _partners.length;
	}

	/// This executes when funds are sent to the contract
	function() {
		if (msg.value > 0) {
			if (funded) {
				if (isPartner(msg.sender)) {
					partnerRecords[msg.sender].loanBalance += msg.value;
				}
			}
			else {
				if (isPartner(msg.sender)) {
					if (partnerRecords[msg.sender].paid) {
						throw;
					}
					else {
						if (msg.value == sharePrice) {
							partnerRecords[msg.sender].paid = true;
							paidPartnerCount += 1;
							if (paidPartnerCount == partnerCount) {
								funded = true;
								Funded();
							}
						}
						else {
							throw;
						}
					}
				}
				else {
					throw;
				}
			}
			Deposit(msg.sender, msg.value);
		}
	}

	/// Adds a proposed transaction to be confirmed by other partners
	function proposeTransaction(address _to, uint _value, bytes _data, string _description) onlyFunded onlyPartner external returns (bytes32) {

		// generate hash for easy specification in confirm and execute
		bytes32 id = sha3(msg.data, block.number);

		// grab the presumably blank transaction
		var transaction = transactions[id];

		transaction.valid = true;
		transaction.to = _to;
		transaction.value = _value;
		transaction.data = _data;
		transaction.description = _description;
		transaction.creator = msg.sender;
		transaction.voteCount = 1;
		transaction.votes[msg.sender] = 1;
		transaction.passed = false;
		transaction.sent = false;

		TransactionProposed(id, msg.sender, _description);

		return id;
	}

	/// Confirms an existing proposed transaction
	function confirmTransaction(bytes32 _id) onlyFunded onlyPartner external {

		var transaction = transactions[_id];

		// ensure this is a transaction we've set up
		if (!transaction.valid)
			throw;

		// ignore second confirmation
		if (transaction.votes[msg.sender] == 1)
			throw;

		// register the vote
		transaction.voteCount += 1;
		transaction.votes[msg.sender] = 1;

		if (transaction.voteCount == partnerCount) {
			transaction.passed = true;
			TransactionPassed(_id, msg.sender, transaction.description);
		}
	}

	/// Executes a passed transaction
	function executeTransaction(bytes32 _id) onlyFunded onlyPartner external {

		var transaction = transactions[_id];

		// ignore transactions that have not passed yet
		if (!transaction.passed)
			throw;

		// ignore transactions that have already been sent
		if (transaction.sent)
			throw;

		// register the sent transaction
		transaction.sent = true;

		// send the transaction
		if (transactions[_id].to.call.value(transactions[_id].value)(transactions[_id].data)) {

			TransactionSent(_id, msg.sender, transaction.description);

			// clear the transaction structure to free memory
			delete transactions[_id];
		}
		else {
			// roll back if the call failed
			transaction.sent = false;
		}
	}

	/// Distribute ETH to a partner
	function distribute(address _partner, uint _amount) onlyDao external {

		// ignore invalid partners
		if (!isPartner(_partner))
			throw;

		partnerRecords[_partner].withdrawableAmount += _amount;
	}

	/// Distribute ETH evenly amongst all partners
	function distributeEvenly(uint _amount) onlyDao external {

		var payout = _amount / partnerCount;

		for (uint i = 0; i < partnerCount; i++) {
			partnerRecords[partners[i]].withdrawableAmount += payout;
		}
	}

	/// Mark down partner's loan and make it available for withdrawal
	function repayLoan(address _partner, uint _amount) onlyDao external {

		// ignore invalid partners
		if (!partnerRecords[_partner].isPartner)
			throw;

		// ignore invalid amounts
		if (_amount > partnerRecords[_partner].loanBalance)
			throw;

		partnerRecords[_partner].loanBalance -= _amount;
		partnerRecords[_partner].withdrawableAmount += _amount;
	}

	/// Allow partner to withdraw funds marked as withdrawable
	function withdraw(uint _amount) onlyFunded onlyPartner external {

		// ignore requests for more than the amount allowed
		if (_amount > partnerRecords[msg.sender].withdrawableAmount)
			throw;

		// ignore requests for more than the available balance
		if (_amount > this.balance)
			throw;

		// mark the withdrawal as successful
		partnerRecords[msg.sender].withdrawableAmount -= _amount;

		// send the wei
		if (msg.sender.send(_amount)) {
			Withdrawal(msg.sender, _amount);
		}
		else {
			// roll back if the send failed
			partnerRecords[msg.sender].withdrawableAmount += _amount;
		}
	}

	/// Dissolve DAO and send the remaining ETH to a beneficiary
	function dissolve(address _beneficiary) onlyDao external {

		// ignore unset beneficiary
		if (_beneficiary == 0)
			throw;

		// prevent lost balance
		if (_beneficiary == address(this))
		    throw;

		suicide(_beneficiary);
	}

	function isPartner(address _address) internal returns (bool) {
		return partnerRecords[_address].isPartner;
	}

}


Further micro-optimization.

Further micro-optimization.

/**
 * @title BlobStore
 * @author Jonathan Brown <jbrown@bluedroplet.com>
 */
contract BlobStore {

    struct BlobInfo {               // Single slot.
        bool updatable;             // Can the blob be updated? Cannot be enabled after creation.
        bool forceNewRevisions;     // When updating always make a new revision. Cannot be disabled after creation.
        bool retractable;           // Can the blob be retracted? Cannot be enabled after creation.
        bool disownable;            // Can the blob be disowned? Cannot be enabled after creation.
        uint32 blockNumber;         // Which block has revision 0 of this blob.
        uint32 numRevisions;        // Number of additional revisions.
        address owner;              // Who created this blob.
    }

    mapping (bytes32 => BlobInfo) idBlobInfo;
    mapping (bytes32 => mapping (uint => bytes32)) idPackedRevisionBlockNumbers;

    event logBlob(bytes32 indexed id, uint indexed revisionId, bytes blob);
    event logRetract(bytes32 indexed id);
    event logDisown(bytes32 indexed id);
    event logSetNotUpdatable(bytes32 indexed id);
    event logSetForceNewRevisions(bytes32 indexed id);
    event logSetNotRetractable(bytes32 indexed id);
    event logSetNotDisownable(bytes32 indexed id);

    // Create a 96-bit id for this contract. This is unique across all blockchains.
    // Wait a few minutes after deploying for this id to settle.
    bytes12 constant public contractId = bytes12(sha3(this, block.blockhash(block.number - 1)));

    modifier noValue() {
        if (msg.value > 0) {
            throw;      // Do not maintain a balance.
        }
        _
    }

    modifier isOwner(bytes32 id) {
        if (idBlobInfo[id].owner != msg.sender) {
            throw;
        }
        _
    }

    modifier isUpdatable(bytes32 id) {
        if (!idBlobInfo[id].updatable) {
            throw;
        }
        _
    }

    modifier isRetractable(bytes32 id) {
        if (!idBlobInfo[id].retractable) {
            throw;
        }
        _
    }

    modifier isDisownable(bytes32 id) {
        if (!idBlobInfo[id].disownable) {
            throw;
        }
        _
    }

    /**
     * @dev Stores a blob in the transaction log. It is guaranteed that each user will get a different id from the same nonce.
     * @param blob Blob that should be stored.
     * @return hash Hash of sender and blob.
     */
    function store(bytes blob, bytes32 nonce, bool updatable, bool forceNewRevisions, bool retractable, bool disownable, bool anon) noValue external returns (bytes32 id) {
        // Determine the id.
        id = contractId | (sha3(msg.sender, nonce) & (2 ** 160 - 1));
        // Make sure this id has not been used before.
        if (idBlobInfo[id].blockNumber != 0) {
            throw;
        }
        // Store blob info in state.
        idBlobInfo[id] = BlobInfo({
            updatable: updatable,
            forceNewRevisions: forceNewRevisions,
            retractable: retractable,
            disownable: disownable,
            numRevisions: 0,
            blockNumber: uint32(block.number),
            owner: anon ? 0 : msg.sender,
        });
        // Store the blob in a log in the current block.
        logBlob(id, 0, blob);
    }

    function setPackedRevisionBlockNumber(bytes32 id, uint offset, bool update) internal {
        if (offset % 8 > 0) {
            if (update) {
                bytes32 slot = idPackedRevisionBlockNumbers[id][offset / 8];
                // Wipe the previous block number.
                slot &= ~bytes32(uint32(-1) * (2 ** ((offset % 8) * 32)));
                // Insert the new block number.
                idPackedRevisionBlockNumbers[id][offset / 8] = slot | bytes32(uint32(block.number) * (2 ** ((offset % 8) * 32)));
            }
            else {
                // Store in the state.
                idPackedRevisionBlockNumbers[id][offset / 8] |= bytes32(uint32(block.number) * (2 ** ((offset % 8) * 32)));
            }
        }
        else {
            // Store the new block number directly in the slot.
            idPackedRevisionBlockNumbers[id][offset / 8] = bytes32(uint32(block.number));
        }
    }

    function update(bytes32 id, bytes blob, bool newRevision) noValue isOwner(id) isUpdatable(id) external returns (uint revisionId) {
        BlobInfo blobInfo = idBlobInfo[id];
        if (newRevision || blobInfo.forceNewRevisions) {
            setPackedRevisionBlockNumber(id, blobInfo.numRevisions++, false);
        }
        else {
            if (blobInfo.numRevisions == 0) {
                blobInfo.blockNumber = uint32(block.number);
            }
            else {
                setPackedRevisionBlockNumber(id, blobInfo.numRevisions - 1, true);
            }
        }
        revisionId = blobInfo.numRevisions;
        // Store the new blob in a log in the current block.
        logBlob(id, revisionId, blob);
    }

    function retract(bytes32 id) noValue isOwner(id) isRetractable(id) external {
        // Delete the packed revision block numbers.
        uint numSlots = (idBlobInfo[id].numRevisions + 7) / 8;
        for (uint i = 0; i < numSlots; i++) {
            delete idPackedRevisionBlockNumbers[id][i];
        }
        // Mark this blob as retracted.
        idBlobInfo[id] = BlobInfo({
            updatable: false,
            forceNewRevisions: false,
            retractable: false,
            disownable: false,
            numRevisions: 0,
            blockNumber: uint32(-1),
            owner: 0,
        });
        // Log that the blob has been retracted.
        logRetract(id);
    }

    function disown(bytes32 id) noValue isOwner(id) isDisownable(id) external {
        // Remove the owner from the blob's state.
        delete idBlobInfo[id].owner;
        // Log as blob as disowned.
        logDisown(id);
    }

    function setNotUpdatable(bytes32 id) noValue isOwner(id) {
        // Record in state that the blob is not updatable.
        idBlobInfo[id].updatable = false;
        // Log that the blob is not updatable.
        logSetNotUpdatable(id);
    }

    function setForceNewTransactions(bytes32 id) noValue isOwner(id) {
        // Record in state that all changes to this blob must be new revisions.
        idBlobInfo[id].forceNewRevisions = true;
        // Log that the blob now forces new revisions.
        logSetForceNewRevisions(id);
    }

    function setNotRetractable(bytes32 id) noValue isOwner(id) {
        // Record in state that the blob is not retractable.
        idBlobInfo[id].retractable = false;
        // Log that the blob is not retractable.
        logSetNotRetractable(id);
    }

    function setNotDisownable(bytes32 id) noValue isOwner(id) {
        // Record in state that the blob is not disownable.
        idBlobInfo[id].disownable = false;
        // Log that the blob is not disownable.
        logSetNotDisownable(id);
    }

    function getInfo(bytes32 id) noValue constant external returns (address owner, bool updatable, bool forceNewRevisions, bool retractable, bool disownable, uint numRevisions, uint latestBlockNumber) {
        owner = idBlobInfo[id].owner;
        updatable = idBlobInfo[id].updatable;
        forceNewRevisions = idBlobInfo[id].forceNewRevisions;
        retractable = idBlobInfo[id].retractable;
        disownable = idBlobInfo[id].disownable;
        numRevisions = idBlobInfo[id].numRevisions;
        latestBlockNumber = getRevisionBlockNumber(id, numRevisions);
    }

    function getOwner(bytes32 id) noValue constant external returns (address owner) {
        owner = idBlobInfo[id].owner;
    }

    function getUpdatable(bytes32 id) noValue constant external returns (bool updatable) {
        updatable = idBlobInfo[id].updatable;
    }

    function getForceNewRevisions(bytes32 id) noValue constant external returns (bool forceNewRevisions) {
        forceNewRevisions = idBlobInfo[id].forceNewRevisions;
    }

    function getRetractable(bytes32 id) noValue constant external returns (bool retractable) {
        retractable = idBlobInfo[id].retractable;
    }

    function getDisownable(bytes32 id) noValue constant external returns (bool disownable) {
        disownable = idBlobInfo[id].disownable;
    }

    function numRevisions(bytes32 id) noValue constant external returns (uint32 numRevisions) {
        numRevisions = idBlobInfo[id].numRevisions;
    }

    function getRevisionBlockNumber(bytes32 id, uint revisionId) noValue constant returns (uint blockNumber) {
        if (revisionId == 0) {
            blockNumber = idBlobInfo[id].blockNumber;
        }
        else {
            bytes32 slot = idPackedRevisionBlockNumbers[id][(revisionId - 1) / 8];
            blockNumber = uint32(uint256(slot) / 2 ** (((revisionId - 1) % 8) * 32));
        }
    }

    function() {
        throw;      // Do not maintain a balance.
    }

}

/**
 * @title BlobStore
 * @author Jonathan Brown <jbrown@bluedroplet.com>
 */
contract BlobStore {

    struct BlobInfo {               // Single slot.
        bool updatable;             // Can the blob be updated? Cannot be enabled after creation.
        bool forceNewRevisions;     // When updating always make a new revision. Cannot be disabled after creation.
        bool retractable;           // Can the blob be retracted? Cannot be enabled after creation.
        bool disownable;            // Can the blob be disowned? Cannot be enabled after creation.
        uint32 blockNumber;         // Which block has revision 0 of this blob.
        uint32 numRevisions;        // Number of additional revisions.
        address owner;              // Who created this blob.
    }

    mapping (bytes32 => BlobInfo) idBlobInfo;
    mapping (bytes32 => mapping (uint => bytes32)) idPackedRevisionBlockNumbers;

    event logBlob(bytes32 indexed id, uint indexed revisionId, bytes blob);
    event logRetract(bytes32 indexed id);
    event logDisown(bytes32 indexed id);
    event logSetNotUpdatable(bytes32 indexed id);
    event logSetForceNewRevisions(bytes32 indexed id);
    event logSetNotRetractable(bytes32 indexed id);
    event logSetNotDisownable(bytes32 indexed id);

    // Create a 96-bit id for this contract. This is unique across all blockchains.
    // Wait a few minutes after deploying for this id to settle.
    bytes12 constant public contractId = bytes12(sha3(this, block.blockhash(block.number - 1)));

    modifier noValue() {
        if (msg.value > 0) {
            throw;      // Do not maintain a balance.
        }
        _
    }

    modifier isOwner(bytes32 id) {
        if (idBlobInfo[id].owner != msg.sender) {
            throw;
        }
        _
    }

    modifier isUpdatable(bytes32 id) {
        if (!idBlobInfo[id].updatable) {
            throw;
        }
        _
    }

    modifier isRetractable(bytes32 id) {
        if (!idBlobInfo[id].retractable) {
            throw;
        }
        _
    }

    modifier isDisownable(bytes32 id) {
        if (!idBlobInfo[id].disownable) {
            throw;
        }
        _
    }

    /**
     * @dev Stores a blob in the transaction log. It is guaranteed that each user will get a different id from the same nonce.
     * @param blob Blob that should be stored.
     * @return hash Hash of sender and blob.
     */
    function store(bytes blob, bytes32 nonce, bool updatable, bool forceNewRevisions, bool retractable, bool disownable, bool anon) noValue external returns (bytes32 id) {
        // Determine the id.
        id = contractId | (sha3(msg.sender, nonce) & (2 ** 160 - 1));
        // Make sure this id has not been used before.
        if (idBlobInfo[id].blockNumber != 0) {
            throw;
        }
        // Store blob info in state.
        idBlobInfo[id] = BlobInfo({
            updatable: updatable,
            forceNewRevisions: forceNewRevisions,
            retractable: retractable,
            disownable: disownable,
            numRevisions: 0,
            blockNumber: uint32(block.number),
            owner: anon ? 0 : msg.sender,
        });
        // Store the blob in a log in the current block.
        logBlob(id, 0, blob);
    }

    function setPackedRevisionBlockNumber(bytes32 id, uint offset, bool update) internal {
        if (offset % 8 > 0) {
            bytes32 slot = idPackedRevisionBlockNumbers[id][offset / 8];
            if (update) {
                slot &= ~bytes32(uint32(-1) * (2 ** ((offset % 8) * 32)));
            }
            slot |= bytes32(uint32(block.number) * (2 ** ((offset % 8) * 32)));
            idPackedRevisionBlockNumbers[id][offset / 8] = slot;
        }
        else {
            idPackedRevisionBlockNumbers[id][offset / 8] = bytes32(uint32(block.number));
        }
    }

    function update(bytes32 id, bytes blob, bool newRevision) noValue isOwner(id) isUpdatable(id) external returns (uint revisionId) {
        BlobInfo blobInfo = idBlobInfo[id];
        if (newRevision || blobInfo.forceNewRevisions) {
            setPackedRevisionBlockNumber(id, blobInfo.numRevisions++, false);
        }
        else {
            if (blobInfo.numRevisions == 0) {
                blobInfo.blockNumber = uint32(block.number);
            }
            else {
                setPackedRevisionBlockNumber(id, blobInfo.numRevisions - 1, true);
            }
        }
        revisionId = blobInfo.numRevisions;
        // Store the new blob in a log in the current block.
        logBlob(id, revisionId, blob);
    }

    function retract(bytes32 id) noValue isOwner(id) isRetractable(id) external {
        // Delete the packed revision block numbers.
        uint numSlots = (idBlobInfo[id].numRevisions + 7) / 8;
        for (uint i = 0; i < numSlots; i++) {
            delete idPackedRevisionBlockNumbers[id][i];
        }
        // Mark this blob as retracted.
        idBlobInfo[id] = BlobInfo({
            updatable: false,
            forceNewRevisions: false,
            retractable: false,
            disownable: false,
            numRevisions: 0,
            blockNumber: uint32(-1),
            owner: 0,
        });
        // Log that the blob has been retracted.
        logRetract(id);
    }

    function disown(bytes32 id) noValue isOwner(id) isDisownable(id) external {
        // Remove the owner from the blob's state.
        delete idBlobInfo[id].owner;
        // Log as blob as disowned.
        logDisown(id);
    }

    function setNotUpdatable(bytes32 id) noValue isOwner(id) {
        // Record in state that the blob is not updatable.
        idBlobInfo[id].updatable = false;
        // Log that the blob is not updatable.
        logSetNotUpdatable(id);
    }

    function setForceNewTransactions(bytes32 id) noValue isOwner(id) {
        // Record in state that all changes to this blob must be new revisions.
        idBlobInfo[id].forceNewRevisions = true;
        // Log that the blob now forces new revisions.
        logSetForceNewRevisions(id);
    }

    function setNotRetractable(bytes32 id) noValue isOwner(id) {
        // Record in state that the blob is not retractable.
        idBlobInfo[id].retractable = false;
        // Log that the blob is not retractable.
        logSetNotRetractable(id);
    }

    function setNotDisownable(bytes32 id) noValue isOwner(id) {
        // Record in state that the blob is not disownable.
        idBlobInfo[id].disownable = false;
        // Log that the blob is not disownable.
        logSetNotDisownable(id);
    }

    function getInfo(bytes32 id) noValue constant external returns (address owner, bool updatable, bool forceNewRevisions, bool retractable, bool disownable, uint numRevisions, uint latestBlockNumber) {
        owner = idBlobInfo[id].owner;
        updatable = idBlobInfo[id].updatable;
        forceNewRevisions = idBlobInfo[id].forceNewRevisions;
        retractable = idBlobInfo[id].retractable;
        disownable = idBlobInfo[id].disownable;
        numRevisions = idBlobInfo[id].numRevisions;
        latestBlockNumber = getRevisionBlockNumber(id, numRevisions);
    }

    function getOwner(bytes32 id) noValue constant external returns (address owner) {
        owner = idBlobInfo[id].owner;
    }

    function getUpdatable(bytes32 id) noValue constant external returns (bool updatable) {
        updatable = idBlobInfo[id].updatable;
    }

    function getForceNewRevisions(bytes32 id) noValue constant external returns (bool forceNewRevisions) {
        forceNewRevisions = idBlobInfo[id].forceNewRevisions;
    }

    function getRetractable(bytes32 id) noValue constant external returns (bool retractable) {
        retractable = idBlobInfo[id].retractable;
    }

    function getDisownable(bytes32 id) noValue constant external returns (bool disownable) {
        disownable = idBlobInfo[id].disownable;
    }

    function numRevisions(bytes32 id) noValue constant external returns (uint32 numRevisions) {
        numRevisions = idBlobInfo[id].numRevisions;
    }

    function getRevisionBlockNumber(bytes32 id, uint revisionId) noValue constant returns (uint blockNumber) {
        if (revisionId == 0) {
            blockNumber = idBlobInfo[id].blockNumber;
        }
        else {
            bytes32 slot = idPackedRevisionBlockNumbers[id][(revisionId - 1) / 8];
            blockNumber = uint32(uint256(slot) / 2 ** (((revisionId - 1) % 8) * 32));
        }
    }

    function() {
        throw;      // Do not maintain a balance.
    }

}


Changed seller deposit

Changed seller deposit

pragma solidity ^0.4.11;

contract Transaction {

	address seller;
	address buyer;
	uint value;

	enum State {Created, Confirmed, Disabled} //default state is the first one.
	State state;

	modifier  onlySeller(address person) { require(person == seller); _; }
	modifier checkValue(uint addedValue) { require(addedValue == 2*value); _; }
	modifier inState(State s) { require(s == state); _; }
	modifier  onlyBuyer(address person) { require(person == buyer); _; }

	event purchaseConfirmed();
	event receiveConfirmed();
	event refundConfirmed();
	event itemShipped();

	function Transaction () public
	    payable
	{
		seller = msg.sender;
		value = msg.value;
	}

	function confirmPurchase() public
		checkValue(msg.value)
		inState(State.Created)
		payable
	{
		buyer = msg.sender;
		state = State.Confirmed;
		purchaseConfirmed();
		itemShipped();
	}

	function confirmReceived() public
		inState(State.Confirmed)
		onlyBuyer(msg.sender)
	{
		receiveConfirmed();
		buyer.transfer(value);
		seller.transfer(this.balance);
		state = State.Disabled;
	}

	function refundBuyer() public
		inState(State.Confirmed)
		onlySeller(msg.sender)
	{
		buyer.transfer(2*value);
		seller.transfer(this.balance);
		state = State.Disabled;
		refundConfirmed();
	}

	function killContract() public
		onlySeller(msg.sender)
		inState(State.Created)
	{
		selfdestruct(seller);
		state = State.Disabled;
	}

}

pragma solidity ^0.4.11;

contract Transaction {

	address seller;
	address buyer;
	uint value;

	enum State {Created, Confirmed, Disabled} //default state is the first one.
	State state;

	modifier  onlySeller(address person) { require(person == seller); _; }
	modifier checkValue(uint addedValue) { require(addedValue == 2*value); _; }
	modifier inState(State s) { require(s == state); _; }
	modifier  onlyBuyer(address person) { require(person == buyer); _; }

	event purchaseConfirmed();
	event receiveConfirmed();
	event refundConfirmed();
	event itemShipped();

	function Transaction () public
	    payable
	{
		seller = msg.sender;
		value = (msg.value*1)/2;
	}

	function confirmPurchase() public
		checkValue(msg.value)
		inState(State.Created)
		payable
	{
		buyer = msg.sender;
		state = State.Confirmed;
		purchaseConfirmed();
		itemShipped();
	}

	function confirmReceived() public
		inState(State.Confirmed)
		onlyBuyer(msg.sender)
	{
		buyer.transfer(value);
		seller.transfer(this.balance);
		state = State.Disabled;
		receiveConfirmed();
	}

	function refundBuyer() public
		inState(State.Confirmed)
		onlySeller(msg.sender)
	{
		buyer.transfer(2*value);
		seller.transfer(this.balance);
		state = State.Disabled;
		refundConfirmed();
	}

	function killContract() public
		onlySeller(msg.sender)
		inState(State.Created)
	{
		selfdestruct(seller);
		state = State.Disabled;
	}

	function deliveryUnsuccesful() public
		onlySeller(msg.sender)
		inState(State.Confirmed)
	{
		buyer.transfer(value*2);
		selfdestruct(seller);
		state = State.Disabled;
	}

}


Contract copy with comments.

Contract copy with comments.

contract fiatcontract {
    uint m_required;
    uint lastNonce;

    uint signers;
    uint numSigners;

    uint m_numOwners;
    mapping(address => uint) ownerIndex;
    mapping(uint => address) owners;

    uint transactionNonce;
    bytes32 transactionHash;
    uint numTransactions;
    mapping(uint => Transaction) transactions;

    uint numSignatures;
    mapping(uint => SigData) signatures;

    // TODO Add balance map

    // Transaction and signature structures
    struct Transaction {
        address to;
        uint value;
    }

    struct SigData {
      uint8 sigV;
      bytes32 sigR;
      bytes32 sigS;
    }

    function confirmTransaction() internal returns (bool) {
        transactionHash = 0x00;
        for(uint i = 0; i < numTransactions; i++) {
          transactionHash = sha3(transactionHash, transactions[i].to, transactions[i].value, transactionNonce);
        }

        if(transactionNonce != lastNonce + 1)
          return false;

        signers = 0;
        numSigners = 0;
        for (i = 0; i < numSignatures && i < 8; i++) {
          address signer = ecrecover(transactionHash, signatures[i].sigV, signatures[i].sigR, signatures[i].sigS);
          uint ownerBit = ownerIndexBit(signer);
          uint ownerValue = 2**ownerBit;
          // TODO Also check if signer == sender
          if(ownerBit > 0 && (signers & ownerValue == 0)) {
            signers |= ownerValue;
            numSigners++;
          }
        }

        if(numSigners >= m_required) return true;

        return false;
    }

    function ownerIndexBit(address addr) internal returns (uint) {
        return ownerIndex[addr];
    }

    function isOwner(address addr) public returns (bool) {
      return (ownerIndex[addr] > 0);
    }

    function getOwners() public returns (address[]) {
      address[] ownersList;
      ownersList.length = m_numOwners;
      for(uint i = 0; i < m_numOwners; i++) {
        ownersList[i] = owners[i+1];
      }

      return ownersList;
    }

    // TODO Add 'admin' address, who is responsible for creation and destruction of tokens
    // constructor is given number of sigs required to do protected "onlymanyowners" transactions
    // as well as the selection of addresses capable of confirming them.
    function multisigwallet(address[] _owners, uint _required) {
        lastNonce = 0;
        for (uint i = 0; i < _owners.length; i++)
        {
        	owners[i+1] = _owners[i];
      		ownerIndex[_owners[i]] = i+1;
        }
        m_numOwners = _owners.length;
        m_required = _required;
    }

    // kills the contract sending everything to `_to`.
    function kill(uint nonce, address[] to, uint[] value,
                   uint8[] sigV, bytes32[] sigR, bytes32[] sigS) external {
        numTransactions = 1;
        transactions[0].to = to[0];
        transactions[0].value = value[0];
        transactionNonce = nonce;

        numSignatures = sigV.length;
        for(uint i = 0; i < sigV.length && i < 8; i++) {
          signatures[i].sigV = sigV[i];
          signatures[i].sigR = sigR[i];
          signatures[i].sigS = sigS[i];
        }

        if(confirmTransaction()) {
          lastNonce = transactionNonce;
          suicide(transactions[0].to);
         }
    }

    // TODO Needs a sender field.
    function execute(uint nonce, address[] to, uint[] value,
                      uint8[] sigV, bytes32[] sigR, bytes32[] sigS) external {
     	numTransactions = to.length;
      for(uint i = 0; i < numTransactions; i++) {
		    transactions[i].to = to[i];
       	transactions[i].value = value[i];
	    }
      transactionNonce = nonce;

      numSignatures = sigV.length;
      for(i = 0; i < numSignatures; i++) {
        signatures[i].sigV = sigV[i];
        signatures[i].sigR = sigR[i];
        signatures[i].sigS = sigS[i];
      }

      if(confirmTransaction()) {
        lastNonce = transactionNonce;
        for(i = 0; i < numTransactions; i++) {
          // TODO Don't send(), update balances in map.
          if(!transactions[i].to.send(transactions[i].value)) {
          	// Rollback the tx if there'x a problem executing it.
          	throw;
	      }
	    }
	  }
    }

    // deposit
    function () {
    }

    // TODO CreationFunction
    // TODO DestructionFunction
}

error: pathspec 'cosigner-fiat/fiat-contract.sol' did not match any file(s) known to git


Toggle broadcast flag

Toggle broadcast flag

import "LockedStateWithFunds.sol";

/**
 * TicTacToeLockedState
 *
 * The LockedState for a TicTacToe game.
 */
contract TicTacToeLockedState is LockedState {

    /* bit mappings for state
     * 0: X gets winnings
     * 1: O gets winnings
     * 2: X forfeits adjudication deposit
     * 3: O forfeits adjudication deposit
     * 4: X forfeits disconnect deposit
     * 5: O forfeits disconnect deposit
     * 6: used to indicate cheating. Doesn't change where funds will be sent
     * note, if tie, bits 0 and 1 should both be 0 to indicate tie
     */
    address addressX;
    address addressO;
    address burner;

    uint[6] funds;

    /**
     * addressX: the address of X
     * addressO: the address of O
     * burner: the address which funds will be burned to (usually 0)
     */
    function TicTacToeLockedState(address _addressX, address _addressO, address _burner) {
        addressX = _addressX;
        addressO = _addressO;
        burner = _burner;
    }

    /*
     * Deposits funds into an escrow account.
     *
     * Accounts are as follows:
     * 0: X's bet
     * 1: O's bet
     * 2: X's adjudication deposit
     * 3: O's adjudication deposit
     * 4: X's disconnect deposit
     * 5: O's disconnect deposit
     */
    function deposit(uint account) external notBroadcast {
        if (account >= 6) {
            throw;
        } else {
            funds[account] += msg.value;
        }
    }

    /**
     * Returns the balance of the account corresponding to the above.
     */
    function getBalance(uint account) constant external notBroadcast returns (uint) {
        if (account >= 6) { throw;
        } else {
            return funds[account];
        }
    }

    /**
     * Checks if a given state is valid.
     * Must be a bytes1 that holds the specified values above.
     * Bits 0 and 1 must not both be 1.
     *
     * state: the state to check
     * returns: true if the state is valid, otherwise false
     */
    function checkState(bytes state) constant returns (bool) {
        if (state.length == 1) {
            return uint8(state[0]) & 0x03 != 0x03;
        } else {
            return false;
        }
    }

    /**
     * Splits the funds according to the state.
     *
     * state: the state that will be broadcast
     * returns: true if transaction sent sucessfully, otherwise false
     */
    function broadcastState(bytes state) external onlyOwner notBroadcast returns (bool) {
        if (!checkState(state)) {
            return false;
        }

        uint sendToX = 0;
        uint sendToO = 0;

        uint uintState = uint(state[0]);

        if (uintState & 0x03 == 0x01) {// X wins, gets bet
            sendToX += funds[0] + funds[1];
        } else if (uintState & 0x03 == 0x02) {// O wins, gets bet
            sendToO += funds[0] + funds[1];
        } else {// tie, they get individual bets back
            sendToX += funds[0];
            sendToO += funds[1];
        }

        // checks if funds should be forfeited
        sendToX += (uintState & 0x04 == 0x00 ? funds[2] : 0) + (uintState & 0x10 == 0x00 ? funds[4] : 0);
        sendToO += (uintState & 0x08 == 0x00 ? funds[3] : 0) + (uintState & 0x20 == 0x00 ? funds[5] : 0);

        if (!addressX.send(sendToX)) {
            throw;
        }

        if (!addressO.send(sendToO)) {
            throw;
        }

        // burns the remaining funds
        if (!burner.send(this.balance)) {
            throw;
        }

        broadcast = true;
        return true;
    }

    // funds should only be sent through the deposit method
    function () {
        throw;
    }
}

import "LockedStateWithFunds.sol";

/**
 * TicTacToeLockedState
 *
 * The LockedState for a TicTacToe game.
 */
contract TicTacToeLockedState is LockedState {

    /* bit mappings for state
     * 0: X gets winnings
     * 1: O gets winnings
     * 2: X forfeits adjudication deposit
     * 3: O forfeits adjudication deposit
     * 4: X forfeits disconnect deposit
     * 5: O forfeits disconnect deposit
     * 6: used to indicate cheating. Doesn't change where funds will be sent
     * note, if tie, bits 0 and 1 should both be 0 to indicate tie
     */
    address addressX;
    address addressO;
    address burner;

    uint[6] funds;

    /**
     * addressX: the address of X
     * addressO: the address of O
     * burner: the address which funds will be burned to (usually 0)
     */
    function TicTacToeLockedState(address _addressX, address _addressO, address _burner) {
        addressX = _addressX;
        addressO = _addressO;
        burner = _burner;
    }

    /*
     * Deposits funds into an escrow account.
     *
     * Accounts are as follows:
     * 0: X's bet
     * 1: O's bet
     * 2: X's adjudication deposit
     * 3: O's adjudication deposit
     * 4: X's disconnect deposit
     * 5: O's disconnect deposit
     */
    function deposit(uint account) external notBroadcast {
        if (account >= 6) {
            throw;
        } else {
            funds[account] += msg.value;
        }
    }

    /**
     * Returns the balance of the account corresponding to the above.
     */
    function getBalance(uint account) constant external notBroadcast returns (uint) {
        if (account >= 6) { throw;
        } else {
            return funds[account];
        }
    }

    /**
     * Checks if a given state is valid.
     * Must be a bytes1 that holds the specified values above.
     * Bits 0 and 1 must not both be 1.
     *
     * state: the state to check
     * returns: true if the state is valid, otherwise false
     */
    function checkState(bytes state) constant returns (bool) {
        if (state.length == 1) {
            return uint8(state[0]) & 0x03 != 0x03;
        } else {
            return false;
        }
    }

    /**
     * Splits the funds according to the state.
     *
     * state: the state that will be broadcast
     * returns: true if transaction sent sucessfully, otherwise false
     */
    function broadcastState(bytes state) external onlyOwner notBroadcast returns (bool) {
        if (!checkState(state)) {
            return false;
        }

        uint sendToX = 0;
        uint sendToO = 0;

        uint uintState = uint(state[0]);

        if (uintState & 0x03 == 0x01) {// X wins, gets bet
            sendToX += funds[0] + funds[1];
        } else if (uintState & 0x03 == 0x02) {// O wins, gets bet
            sendToO += funds[0] + funds[1];
        } else {// tie, they get individual bets back
            sendToX += funds[0];
            sendToO += funds[1];
        }

        // checks if funds should be forfeited
        sendToX += (uintState & 0x04 == 0x00 ? funds[2] : 0) + (uintState & 0x10 == 0x00 ? funds[4] : 0);
        sendToO += (uintState & 0x08 == 0x00 ? funds[3] : 0) + (uintState & 0x20 == 0x00 ? funds[5] : 0);

        if (!addressX.send(sendToX)) {
            throw;
        }

        if (!addressO.send(sendToO)) {
            throw;
        }

        // burns the remaining funds
        if (!burner.send(this.balance)) {
            throw;
        }

        return true;
    }

    // funds should only be sent through the deposit method
    function () {
        throw;
    }
}