Remove _setSubnodeOwnerAndWrap()

Remove _setSubnodeOwnerAndWrap()

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "./ERC1155Fuse.sol";
import "./Controllable.sol";
import "./INameWrapper.sol";
import "./IMetadataService.sol";
import "../registry/ENS.sol";
import "../ethregistrar/IBaseRegistrar.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./BytesUtil.sol";

error Unauthorised(bytes32 node, address addr);
error NameNotFound();
error IncompatibleParent();
error IncompatibleName(bytes name);
error IncorrectTokenType();
error LabelMismatch(bytes32 labelHash, bytes32 expectedLabelhash);
error LabelTooShort();
error LabelTooLong(string label);
error IncorrectTargetOwner(address owner);

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

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

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

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

        _setData(
            uint256(ETH_NODE),
            address(0x0),
            uint96(PARENT_CANNOT_CONTROL | CANNOT_UNWRAP)
        );
        _setData(
            uint256(ROOT_NODE),
            address(0x0),
            uint96(PARENT_CANNOT_CONTROL | 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) {
        if (!isTokenOwnerOrApproved(node, msg.sender)) {
            revert Unauthorised(node, msg.sender);
        }

        _;
    }

    /**
     * @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)
    {
        address owner = ownerOf(uint256(node));
        return owner == addr || isApprovedForAll(owner, 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];
        if (name.length == 0) {
            revert NameNotFound();
        }
        (, 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,
        address resolver
    ) public override {
        uint256 tokenId = uint256(keccak256(bytes(label)));
        address registrant = registrar.ownerOf(tokenId);
        if (
            registrant != msg.sender &&
            !isApprovedForAll(registrant, msg.sender) &&
            !registrar.isApprovedForAll(registrant, msg.sender)
        ) {
            revert Unauthorised(
                _makeNode(ETH_NODE, bytes32(tokenId)),
                msg.sender
            );
        }

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

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

        _wrapETH2LD(label, wrappedOwner, _fuses, resolver);
    }

    /**
     * @dev Registers a new .eth second-level domain and wraps it.
     *      Only callable by authorised controllers.
     * @param label The label to register (Eg, 'foo' for 'foo.eth').
     * @param wrappedOwner The owner of the wrapped name.
     * @param duration The duration, in seconds, to register the name for.
     * @param resolver The resolver address to set on the ENS registry (optional).
     * @return expires The expiry date of the new name, in seconds since the Unix epoch.
     */
    function registerAndWrapETH2LD(
        string calldata label,
        address wrappedOwner,
        uint256 duration,
        address resolver,
        uint96 _fuses
    ) external override onlyController returns (uint256 expires) {
        uint256 tokenId = uint256(keccak256(bytes(label)));

        expires = registrar.register(tokenId, address(this), duration);
        _wrapETH2LD(label, wrappedOwner, _fuses, resolver);
    }

    /**
     * @dev Renews a .eth second-level domain.
     *      Only callable by authorised controllers.
     * @param tokenId The hash of the label to register (eg, `keccak256('foo')`, for 'foo.eth').
     * @param duration The number of seconds to renew the name for.
     * @return expires The expiry date of the name, in seconds since the Unix epoch.
     */
    function renew(uint256 tokenId, uint256 duration)
        external
        override
        onlyController
        returns (uint256 expires)
    {
        return registrar.renew(tokenId, duration);
    }

    /**
     * @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,
        address resolver
    ) public override {
        (bytes32 labelhash, uint256 offset) = name.readLabel(0);
        bytes32 parentNode = name.namehash(offset);
        bytes32 node = _makeNode(parentNode, labelhash);

        if (parentNode == ETH_NODE) {
            revert IncompatibleParent();
        }

        address owner = ens.owner(node);

        if (
            owner != msg.sender &&
            !isApprovedForAll(owner, msg.sender) &&
            !ens.isApprovedForAll(owner, msg.sender)
        ) {
            revert Unauthorised(node, msg.sender);
        }

        if (resolver != address(0)) {
            ens.setResolver(node, resolver);
        }

        ens.setOwner(node, address(this));

        _wrap(node, name, wrappedOwner, _fuses);
    }

    /**
     * @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 labelhash labelhash of the .eth domain
     * @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 labelhash,
        address newRegistrant,
        address newController
    ) public override onlyTokenOwner(_makeNode(ETH_NODE, labelhash)) {
        _unwrap(_makeNode(ETH_NODE, labelhash), newController);
        registrar.transferFrom(
            address(this),
            newRegistrant,
            uint256(labelhash)
        );
    }

    /**
     * @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 labelhash labelhash of the .eth domain
     * @param newController sets the owner in the registry to this address
     */

    function unwrap(
        bytes32 parentNode,
        bytes32 labelhash,
        address newController
    ) public override onlyTokenOwner(_makeNode(parentNode, labelhash)) {
        if (parentNode == ETH_NODE) {
            revert IncompatibleParent();
        }
        _unwrap(_makeNode(parentNode, labelhash), 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)
    {
        if (_fuses & PARENT_CANNOT_CONTROL != 0) {
            // Only the parent can burn the PARENT_CANNOT_REPLACE fuse.
            revert Unauthorised(node, msg.sender);
        }

        (address owner, uint96 fuses) = getData(uint256(node));

        uint96 newFuses = fuses | _fuses;

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

        emit FusesBurned(node, newFuses);
    }

    /**
     * @notice Burns fuses for a subdomain owned or authorised by the caller.
     * @dev Fuse burns are always additive and will not unburn already burnt fuses
     * @param parentNode namehash of the parent name. e.g. vitalik.xyz would be namehash('vitalik.xyz')
     * @param labelhash keccak256 hash of the subdomain label
     * @param _fuses Fuses you want to burn.
     */
    function burnChildFuses(
        bytes32 parentNode,
        bytes32 labelhash,
        uint96 _fuses
    )
        public
        override
        onlyTokenOwner(parentNode)
        operationAllowed(
            _makeNode(parentNode, labelhash),
            PARENT_CANNOT_CONTROL
        )
    {
        bytes32 subnode = _makeNode(parentNode, labelhash);
        (address owner, uint96 fuses) = getData(uint256(subnode));

        uint96 newFuses = fuses | _fuses;

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

        emit FusesBurned(subnode, newFuses);
    }

    /**
     * @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 setSubnodeOwner(
        bytes32 parentNode,
        string calldata label,
        address newOwner,
        uint96 _fuses
    )
        public
        onlyTokenOwner(parentNode)
        canCallSetSubnodeOwner(parentNode, keccak256(bytes(label)))
        returns (bytes32 node)
    {
        bytes32 labelhash = keccak256(bytes(label));
        node = _makeNode(parentNode, labelhash);

        if (ens.owner(node) != address(this)) {
            ens.setSubnodeOwner(parentNode, labelhash, address(this));
            _addLabelAndWrap(parentNode, label, newOwner, _fuses);
        } else {
            _transferAndBurnFuses(parentNode, labelhash, 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 setSubnodeRecord(
        bytes32 parentNode,
        string calldata label,
        address newOwner,
        address resolver,
        uint64 ttl,
        uint96 _fuses
    )
        public
        onlyTokenOwner(parentNode)
        canCallSetSubnodeOwner(parentNode, keccak256(bytes(label)))
    {
        bytes32 labelhash = keccak256(bytes(label));
        bytes32 node = _makeNode(parentNode, labelhash);

        if (ens.owner(node) != address(this)) {
            ens.setSubnodeRecord(
                parentNode,
                labelhash,
                address(this),
                resolver,
                ttl
            );
            _addLabelAndWrap(parentNode, label, newOwner, _fuses);
        } else {
            ens.setSubnodeRecord(
                parentNode,
                labelhash,
                address(this),
                resolver,
                ttl
            );
            _transferAndBurnFuses(parentNode, labelhash, 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));
        if (fuses & fuseMask != 0) {
            revert OperationProhibited(node);
        }
        _;
    }

    /**
     * @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 labelhash labelhash of the name to check
     */

    modifier canCallSetSubnodeOwner(bytes32 node, bytes32 labelhash) {
        bytes32 subnode = _makeNode(node, labelhash);
        address owner = ens.owner(subnode);

        if (owner == address(0)) {
            (, uint96 fuses) = getData(uint256(node));
            if (fuses & CANNOT_CREATE_SUBDOMAIN != 0) {
                revert OperationProhibited(node);
            }
        } else {
            (, uint96 subnodeFuses) = getData(uint256(subnode));
            if (subnodeFuses & PARENT_CANNOT_CONTROL != 0) {
                revert OperationProhibited(node);
            }
        }

        _;
    }

    /**
     * @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
        if (msg.sender != address(registrar)) {
            revert IncorrectTokenType();
        }

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

        bytes32 labelhash = bytes32(tokenId);
        bytes32 labelhashFromData = keccak256(bytes(label));

        if (labelhashFromData != labelhash) {
            revert LabelMismatch(labelhashFromData, labelhash);
        }

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

        _wrapETH2LD(label, owner, fuses, resolver);

        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 labelhash)
        private
        pure
        returns (bytes32)
    {
        return keccak256(abi.encodePacked(node, labelhash));
    }

    function _addLabel(string memory label, bytes memory name)
        internal
        pure
        returns (bytes memory ret)
    {
        if (bytes(label).length < 1) {
            revert LabelTooShort();
        }
        if (bytes(label).length > 255) {
            revert LabelTooLong(label);
        }
        return abi.encodePacked(uint8(bytes(label).length), label, name);
    }

    function _mint(
        bytes32 node,
        address wrappedOwner,
        uint96 _fuses
    ) internal override {
        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));
        }
        super._mint(node, wrappedOwner, _fuses);
    }

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

        _mint(node, wrappedOwner, fuses);

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

    function _addLabelAndWrap(
        bytes32 parentNode,
        string memory label,
        address newOwner,
        uint96 _fuses
    ) internal {
        bytes32 labelhash = keccak256(bytes(label));
        bytes32 node = _makeNode(parentNode, labelhash);
        bytes memory name = _addLabel(label, names[parentNode]);
        _wrap(node, name, newOwner, _fuses);
    }

    function _transferAndBurnFuses(
        bytes32 parentNode,
        bytes32 labelhash,
        address newOwner,
        uint96 _fuses
    ) internal {
        bytes32 subnode = _makeNode(parentNode, labelhash);
        (, uint96 fuses) = getData(uint256(subnode));

        uint96 newFuses = fuses | _fuses;

        _setData(uint256(subnode), newOwner, newFuses);
        emit TransferSingle(
            msg.sender,
            address(0x0),
            newOwner,
            uint256(subnode),
            1
        );
        emit FusesBurned(subnode, newFuses);
    }

    function _wrapETH2LD(
        string memory label,
        address wrappedOwner,
        uint96 _fuses,
        address resolver
    ) private returns (bytes32 labelhash) {
        labelhash = keccak256(bytes(label));
        bytes32 node = _makeNode(ETH_NODE, labelhash);
        bytes memory name = _addLabel(label, "\x03eth\x00");

        if (resolver != address(0)) {
            ens.setResolver(node, resolver);
        }

        // mint a new ERC1155 token with fuses
        // Set PARENT_CANNOT_REPLACE to reflect wrapper + registrar control over the 2LD
        _wrap(node, name, wrappedOwner, _fuses | PARENT_CANNOT_CONTROL);
    }

    function _unwrap(bytes32 node, address newOwner) private {
        if (newOwner == address(0x0) || newOwner == address(this)) {
            revert IncorrectTargetOwner(newOwner);
        }

        if (allFusesBurned(node, CANNOT_UNWRAP)) {
            revert OperationProhibited(node);
        }

        // 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 {
        // Other than PARENT_CANNOT_CONTROL, no other fuse can be set without CANNOT_UNWRAP
        if (fuses & ~PARENT_CANNOT_CONTROL != 0 && fuses & CANNOT_UNWRAP == 0) {
            revert OperationProhibited(bytes32(tokenId));
        }
        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 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(node, PARENT_CANNOT_CONTROL) ||
            !allFusesBurned(parentNode, CANNOT_UNWRAP)
        ) {
            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);
        }
        return (NameSafety.Safe, 0);
    }
}

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "./ERC1155Fuse.sol";
import "./Controllable.sol";
import "./INameWrapper.sol";
import "./IMetadataService.sol";
import "../registry/ENS.sol";
import "../ethregistrar/IBaseRegistrar.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./BytesUtil.sol";

error Unauthorised(bytes32 node, address addr);
error NameNotFound();
error IncompatibleParent();
error IncompatibleName(bytes name);
error IncorrectTokenType();
error LabelMismatch(bytes32 labelHash, bytes32 expectedLabelhash);
error LabelTooShort();
error LabelTooLong(string label);
error IncorrectTargetOwner(address owner);

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

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

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

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

        _setData(
            uint256(ETH_NODE),
            address(0x0),
            uint96(PARENT_CANNOT_CONTROL | CANNOT_UNWRAP)
        );
        _setData(
            uint256(ROOT_NODE),
            address(0x0),
            uint96(PARENT_CANNOT_CONTROL | 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) {
        if (!isTokenOwnerOrApproved(node, msg.sender)) {
            revert Unauthorised(node, msg.sender);
        }

        _;
    }

    /**
     * @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)
    {
        address owner = ownerOf(uint256(node));
        return owner == addr || isApprovedForAll(owner, 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];
        if (name.length == 0) {
            revert NameNotFound();
        }
        (, 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,
        address resolver
    ) public override {
        uint256 tokenId = uint256(keccak256(bytes(label)));
        address registrant = registrar.ownerOf(tokenId);
        if (
            registrant != msg.sender &&
            !isApprovedForAll(registrant, msg.sender) &&
            !registrar.isApprovedForAll(registrant, msg.sender)
        ) {
            revert Unauthorised(
                _makeNode(ETH_NODE, bytes32(tokenId)),
                msg.sender
            );
        }

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

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

        _wrapETH2LD(label, wrappedOwner, _fuses, resolver);
    }

    /**
     * @dev Registers a new .eth second-level domain and wraps it.
     *      Only callable by authorised controllers.
     * @param label The label to register (Eg, 'foo' for 'foo.eth').
     * @param wrappedOwner The owner of the wrapped name.
     * @param duration The duration, in seconds, to register the name for.
     * @param resolver The resolver address to set on the ENS registry (optional).
     * @return expires The expiry date of the new name, in seconds since the Unix epoch.
     */
    function registerAndWrapETH2LD(
        string calldata label,
        address wrappedOwner,
        uint256 duration,
        address resolver,
        uint96 _fuses
    ) external override onlyController returns (uint256 expires) {
        uint256 tokenId = uint256(keccak256(bytes(label)));

        expires = registrar.register(tokenId, address(this), duration);
        _wrapETH2LD(label, wrappedOwner, _fuses, resolver);
    }

    /**
     * @dev Renews a .eth second-level domain.
     *      Only callable by authorised controllers.
     * @param tokenId The hash of the label to register (eg, `keccak256('foo')`, for 'foo.eth').
     * @param duration The number of seconds to renew the name for.
     * @return expires The expiry date of the name, in seconds since the Unix epoch.
     */
    function renew(uint256 tokenId, uint256 duration)
        external
        override
        onlyController
        returns (uint256 expires)
    {
        return registrar.renew(tokenId, duration);
    }

    /**
     * @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,
        address resolver
    ) public override {
        (bytes32 labelhash, uint256 offset) = name.readLabel(0);
        bytes32 parentNode = name.namehash(offset);
        bytes32 node = _makeNode(parentNode, labelhash);

        if (parentNode == ETH_NODE) {
            revert IncompatibleParent();
        }

        address owner = ens.owner(node);

        if (
            owner != msg.sender &&
            !isApprovedForAll(owner, msg.sender) &&
            !ens.isApprovedForAll(owner, msg.sender)
        ) {
            revert Unauthorised(node, msg.sender);
        }

        if (resolver != address(0)) {
            ens.setResolver(node, resolver);
        }

        ens.setOwner(node, address(this));

        _wrap(node, name, wrappedOwner, _fuses);
    }

    /**
     * @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 labelhash labelhash of the .eth domain
     * @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 labelhash,
        address newRegistrant,
        address newController
    ) public override onlyTokenOwner(_makeNode(ETH_NODE, labelhash)) {
        _unwrap(_makeNode(ETH_NODE, labelhash), newController);
        registrar.transferFrom(
            address(this),
            newRegistrant,
            uint256(labelhash)
        );
    }

    /**
     * @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 labelhash labelhash of the .eth domain
     * @param newController sets the owner in the registry to this address
     */

    function unwrap(
        bytes32 parentNode,
        bytes32 labelhash,
        address newController
    ) public override onlyTokenOwner(_makeNode(parentNode, labelhash)) {
        if (parentNode == ETH_NODE) {
            revert IncompatibleParent();
        }
        _unwrap(_makeNode(parentNode, labelhash), 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)
    {
        if (_fuses & PARENT_CANNOT_CONTROL != 0) {
            // Only the parent can burn the PARENT_CANNOT_REPLACE fuse.
            revert Unauthorised(node, msg.sender);
        }

        (address owner, uint96 fuses) = getData(uint256(node));

        uint96 newFuses = fuses | _fuses;

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

        emit FusesBurned(node, newFuses);
    }

    /**
     * @notice Burns fuses for a subdomain owned or authorised by the caller.
     * @dev Fuse burns are always additive and will not unburn already burnt fuses
     * @param parentNode namehash of the parent name. e.g. vitalik.xyz would be namehash('vitalik.xyz')
     * @param labelhash keccak256 hash of the subdomain label
     * @param _fuses Fuses you want to burn.
     */
    function burnChildFuses(
        bytes32 parentNode,
        bytes32 labelhash,
        uint96 _fuses
    )
        public
        override
        onlyTokenOwner(parentNode)
        operationAllowed(
            _makeNode(parentNode, labelhash),
            PARENT_CANNOT_CONTROL
        )
    {
        bytes32 subnode = _makeNode(parentNode, labelhash);
        (address owner, uint96 fuses) = getData(uint256(subnode));

        uint96 newFuses = fuses | _fuses;

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

        emit FusesBurned(subnode, newFuses);
    }

    /**
     * @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 setSubnodeOwner(
        bytes32 parentNode,
        string calldata label,
        address newOwner,
        uint96 _fuses
    )
        public
        onlyTokenOwner(parentNode)
        canCallSetSubnodeOwner(parentNode, keccak256(bytes(label)))
        returns (bytes32 node)
    {
        bytes32 labelhash = keccak256(bytes(label));
        node = _makeNode(parentNode, labelhash);

        if (ens.owner(node) != address(this)) {
            _setSubnodeOwnerAndWrap(parentNode, label, newOwner, _fuses);
        } else {
            _transferAndBurnFuses(parentNode, labelhash, 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 setSubnodeRecord(
        bytes32 parentNode,
        string calldata label,
        address newOwner,
        address resolver,
        uint64 ttl,
        uint96 _fuses
    )
        public
        onlyTokenOwner(parentNode)
        canCallSetSubnodeOwner(parentNode, keccak256(bytes(label)))
    {
        bytes32 labelhash = keccak256(bytes(label));
        bytes32 node = _makeNode(parentNode, labelhash);

        if (ens.owner(node) != address(this)) {
            ens.setSubnodeRecord(
                parentNode,
                labelhash,
                address(this),
                resolver,
                ttl
            );
            _addLabelAndWrap(parentNode, label, newOwner, _fuses);
        } else {
            ens.setSubnodeRecord(
                parentNode,
                labelhash,
                address(this),
                resolver,
                ttl
            );
            _transferAndBurnFuses(parentNode, labelhash, 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));
        if (fuses & fuseMask != 0) {
            revert OperationProhibited(node);
        }
        _;
    }

    /**
     * @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 labelhash labelhash of the name to check
     */

    modifier canCallSetSubnodeOwner(bytes32 node, bytes32 labelhash) {
        bytes32 subnode = _makeNode(node, labelhash);
        address owner = ens.owner(subnode);

        if (owner == address(0)) {
            (, uint96 fuses) = getData(uint256(node));
            if (fuses & CANNOT_CREATE_SUBDOMAIN != 0) {
                revert OperationProhibited(node);
            }
        } else {
            (, uint96 subnodeFuses) = getData(uint256(subnode));
            if (subnodeFuses & PARENT_CANNOT_CONTROL != 0) {
                revert OperationProhibited(node);
            }
        }

        _;
    }

    /**
     * @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
        if (msg.sender != address(registrar)) {
            revert IncorrectTokenType();
        }

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

        bytes32 labelhash = bytes32(tokenId);
        bytes32 labelhashFromData = keccak256(bytes(label));

        if (labelhashFromData != labelhash) {
            revert LabelMismatch(labelhashFromData, labelhash);
        }

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

        _wrapETH2LD(label, owner, fuses, resolver);

        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 labelhash)
        private
        pure
        returns (bytes32)
    {
        return keccak256(abi.encodePacked(node, labelhash));
    }

    function _addLabel(string memory label, bytes memory name)
        internal
        pure
        returns (bytes memory ret)
    {
        if (bytes(label).length < 1) {
            revert LabelTooShort();
        }
        if (bytes(label).length > 255) {
            revert LabelTooLong(label);
        }
        return abi.encodePacked(uint8(bytes(label).length), label, name);
    }

    function _mint(
        bytes32 node,
        address wrappedOwner,
        uint96 _fuses
    ) internal override {
        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));
        }
        super._mint(node, wrappedOwner, _fuses);
    }

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

        _mint(node, wrappedOwner, fuses);

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

    function _addLabelAndWrap(
        bytes32 parentNode,
        string memory label,
        address newOwner,
        uint96 _fuses
    ) internal {
        bytes32 labelhash = keccak256(bytes(label));
        bytes32 node = _makeNode(parentNode, labelhash);
        bytes memory name = _addLabel(label, names[parentNode]);
        _wrap(node, name, newOwner, _fuses);
    }

    function _setSubnodeOwnerAndWrap(
        bytes32 parentNode,
        string memory label,
        address newOwner,
        uint96 _fuses
    ) internal {
        bytes32 labelhash = keccak256(bytes(label));
        bytes32 node = _makeNode(parentNode, labelhash);
        bytes memory name = _addLabel(label, names[parentNode]);
        ens.setSubnodeOwner(parentNode, labelhash, address(this));
        _wrap(node, name, newOwner, _fuses);
    }

    function _transferAndBurnFuses(
        bytes32 parentNode,
        bytes32 labelhash,
        address newOwner,
        uint96 _fuses
    ) internal {
        bytes32 subnode = _makeNode(parentNode, labelhash);
        (, uint96 fuses) = getData(uint256(subnode));

        uint96 newFuses = fuses | _fuses;

        _setData(uint256(subnode), newOwner, newFuses);
        emit TransferSingle(
            msg.sender,
            address(0x0),
            newOwner,
            uint256(subnode),
            1
        );
        emit FusesBurned(subnode, newFuses);
    }

    function _wrapETH2LD(
        string memory label,
        address wrappedOwner,
        uint96 _fuses,
        address resolver
    ) private returns (bytes32 labelhash) {
        labelhash = keccak256(bytes(label));
        bytes32 node = _makeNode(ETH_NODE, labelhash);
        bytes memory name = _addLabel(label, "\x03eth\x00");

        if (resolver != address(0)) {
            ens.setResolver(node, resolver);
        }

        // mint a new ERC1155 token with fuses
        // Set PARENT_CANNOT_REPLACE to reflect wrapper + registrar control over the 2LD
        _wrap(node, name, wrappedOwner, _fuses | PARENT_CANNOT_CONTROL);
    }

    function _unwrap(bytes32 node, address newOwner) private {
        if (newOwner == address(0x0) || newOwner == address(this)) {
            revert IncorrectTargetOwner(newOwner);
        }

        if (allFusesBurned(node, CANNOT_UNWRAP)) {
            revert OperationProhibited(node);
        }

        // 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 {
        // Other than PARENT_CANNOT_CONTROL, no other fuse can be set without CANNOT_UNWRAP
        if (fuses & ~PARENT_CANNOT_CONTROL != 0 && fuses & CANNOT_UNWRAP == 0) {
            revert OperationProhibited(bytes32(tokenId));
        }
        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 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(node, PARENT_CANNOT_CONTROL) ||
            !allFusesBurned(parentNode, CANNOT_UNWRAP)
        ) {
            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);
        }
        return (NameSafety.Safe, 0);
    }
}


Update comment

Update comment

import './Conference.sol';
import './zeppelin/PullPaymentCapable.sol';
import './zeppelin/Rejector.sol';

/*
 * Bounty
 * This bounty will pay out if you can cause a Conference's balance
 * to be lower from its totalBalance, which would mean that it doesn't
 * have sufficient ether for everyone to withdraw.
 */
contract Bounty is PullPaymentCapable, Rejector{
  uint public totalBounty;
  bool public claimed;
  mapping(address => address) public researchers;
  event TargetCreation(address createdAddress);
  event Error(string message);

  function contribute() {
    totalBounty = msg.value;
    if (claimed) throw;
  }

  function createTarget() returns(Conference) {
    Conference target = new Conference();
    researchers[target] = msg.sender;
    TargetCreation(target);
    return target;
  }

  modifier hasResearcher(Conference target) {
    address researcher = researchers[target];
    if (researcher != 0){
      _
    }else{
      Error('there are no researcher');
    }
  }

  modifier hasBug(Conference target) {
    if (target.totalBalance() > target.balance){
      _
    }else{
      Error('No security breach');
    }
  }

  function claim(Conference target) hasResearcher(target) hasBug(target){
    address researcher = researchers[target];
    asyncSend(researcher, this.balance);
    totalBounty = 0;
    claimed = true;
  }
}

import './Conference.sol';
import './zeppelin/PullPaymentCapable.sol';
import './zeppelin/Rejector.sol';

/*
 * Bounty
 * This bounty will pay out if you can cause a Conference's balance
 * to be different from its totalBalance, which would mean that it doesn't
 * have sufficient ether for everyone to withdraw.
 */
contract Bounty is PullPaymentCapable, Rejector{
  uint public totalBounty;
  bool public claimed;
  mapping(address => address) public researchers;
  event TargetCreation(address createdAddress);
  event Error(string message);

  function contribute() {
    totalBounty = msg.value;
    if (claimed) throw;
  }

  function createTarget() returns(Conference) {
    Conference target = new Conference();
    researchers[target] = msg.sender;
    TargetCreation(target);
    return target;
  }

  modifier hasResearcher(Conference target) {
    address researcher = researchers[target];
    if (researcher != 0){
      _
    }else{
      Error('there are no researcher');
    }
  }

  modifier hasBug(Conference target) {
    if (target.totalBalance() > target.balance){
      _
    }else{
      Error('No security breach');
    }
  }

  function claim(Conference target) hasResearcher(target) hasBug(target){
    address researcher = researchers[target];
    asyncSend(researcher, this.balance);
    totalBounty = 0;
    claimed = true;
  }
}


Changing returnInvestment modifier

Changing returnInvestment modifier

pragma solidity ^0.4.18;

import './AssetEvents.sol';
import '../token/Token.sol';
import "zeppelin-solidity/contracts/math/SafeMath.sol";

// Defines methods and control modifiers for an investment
contract AssetLibrary is AssetEvents {

    using SafeMath for uint256;

    // Asset owner
    address public owner;
    // Protocol
    address public protocol;
    // Asset currency
    string public currency;
    // Asset fixed value
    uint256 public value;
    //Value bought
    uint256 public boughtValue;
    // period to return the investment
    uint256 public paybackDays;
    // Gross return of investment
    uint256 public grossReturn;
    // Asset buyer
    address public investor;
    // Protocol version
    string public protocolVersion;
    // investment timestamp
    uint public investedAt;

    // asset fuel
    Token public token;
    uint256 public tokenFuel;

    // sell data
    struct Sell {
        uint256 value;
        address buyer;
    }

    Sell public sellData;

    // possible stages of an asset
    enum Status {
        AVAILABLE,
        PENDING_OWNER_AGREEMENT,
        INVESTED,
        FOR_SALE,
        PENDING_INVESTOR_AGREEMENT,
        RETURNED,
        DELAYED_RETURN
    }
    Status public status;

    // Checks the current asset's status
    modifier hasStatus(Status _status) {
        assert(status == _status);
        _;
    }

    // Checks if the owner is the caller
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    // Checks if the investor is the caller
    modifier onlyInvestor() {
        require(msg.sender == investor);
        _;
    }

    modifier protocolOrInvestor() {
        require(msg.sender == investor || msg.sender == protocol);
        _;
    }

    modifier protocolOrOwner() {
        require(msg.sender == owner || msg.sender == protocol);
        _;
    }

    modifier onlyDelayed(){
        require(isDelayed());
        _;
    }

    function isDelayed()
        view
        internal
        returns(bool)
    {
        return now > investedAt + paybackDays * 1 days;
    }

    // Refund and remove the current investor and make the asset available for investments
    function makeAvailable()
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        private
        returns(address, uint256)
    {
        status = Status.AVAILABLE;
        uint256 investedValue = this.balance;
        investor.transfer(investedValue);
        address currentInvestor = investor;
        investor = address(0);
        investedAt = uint(0);
        return (currentInvestor, investedValue);
    }

    function withdrawTokens(address _recipient, uint256 _amount)
        private
        returns(bool)
    {
        assert(tokenFuel >= _amount);
        require(token.transfer(_recipient, _amount));
        TokenWithdrawal(_recipient, _amount);
        tokenFuel = tokenFuel.sub(_amount);
        return true;
    }

    // Add investment interest in this asset and retain the funds within the smart contract
    function invest(address _investor) payable
         hasStatus(Status.AVAILABLE)
         external
         returns(bool)
    {
        status = Status.PENDING_OWNER_AGREEMENT;
        investor = _investor;
        investedAt = now;
        Invested(owner, investor, this.balance);
        return true;
    }

    // Cancel the pending investment
    function cancelInvestment()
        protocolOrInvestor
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        external
        returns(bool)
    {
        var (currentInvestor, investedValue) = makeAvailable();
        Canceled(owner, currentInvestor, investedValue);
        return true;
    }

    // Accept the investor as the asset buyer and withdraw funds
    function withdrawFunds()
        protocolOrOwner
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        external
        returns(bool)
    {
        status = Status.INVESTED;
        uint256 _value = this.balance;
        owner.transfer(_value);
        Withdrawal(owner, investor, _value);
        return true;
    }

    // Refuse the pending investment
    function refuseInvestment()
        protocolOrOwner
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        external
        returns(bool)
    {
        var (currentInvestor, investedValue) = makeAvailable();
        Refused(owner, currentInvestor, investedValue);
        return true;
    }

    function sell(uint256 _sellValue)
        protocolOrInvestor
        hasStatus(Status.INVESTED)
        external
        returns(bool)
    {
        status = Status.FOR_SALE;
        sellData.value = _sellValue;
        ForSale(msg.sender, _sellValue);
        return true;
    }

    function cancelSellOrder()
        protocolOrInvestor
        hasStatus(Status.FOR_SALE)
        external
        returns(bool)
    {
        status = Status.INVESTED;
        sellData.value = uint256(0);
        CanceledSell(investor, value);
        return true;
    }

    function buy(address _buyer) payable
        hasStatus(Status.FOR_SALE)
        external
        returns(bool)
    {
        status = Status.PENDING_INVESTOR_AGREEMENT;
        sellData.buyer = _buyer;
        Invested(investor, _buyer, msg.value);
        return true;
    }

    function cancelSale()
        hasStatus(Status.PENDING_INVESTOR_AGREEMENT)
        external
        returns(bool)
    {
        require(msg.sender == protocol || msg.sender == sellData.buyer);
        status = Status.FOR_SALE;
        address buyer = sellData.buyer;
        uint256 _value = this.balance;
        buyer.transfer(_value);
        sellData.buyer = address(0);
        Canceled(investor, buyer, _value);
        return true;
    }

    // Refunds asset's buyer and became available for sale again
    function refuseSale()
        protocolOrInvestor
        hasStatus(Status.PENDING_INVESTOR_AGREEMENT)
        external
        returns(bool)
    {
        status = Status.FOR_SALE;
        address buyer = sellData.buyer;
        uint256 _value = this.balance;
        buyer.transfer(_value);
        sellData.buyer = address(0);
        Refused(investor, buyer, _value);
        return true;
    }

    // Withdraw funds, clear the sell data and change investor's address
    function acceptSale()
        protocolOrInvestor
        hasStatus(Status.PENDING_INVESTOR_AGREEMENT)
        external
        returns(bool)
    {
        status = Status.INVESTED;
        address currentInvestor = investor;
        uint256 _value = this.balance;
        currentInvestor.transfer(_value);
        investor = sellData.buyer;
        boughtValue = sellData.value;
        sellData.buyer = address(0);
        sellData.value = uint256(0);
        Withdrawal(currentInvestor, investor, _value);
        return true;
    }

    function returnInvestment() payable
        protocolOrOwner
        external
        returns(bool)
    {
        assert(status == Status.INVESTED || status == Status.FOR_SALE || status == Status.PENDING_INVESTOR_AGREEMENT);
        Status currentStatus = status;
        bool _isDelayed = isDelayed();
        status = _isDelayed ? Status.DELAYED_RETURN : Status.RETURNED;
        if(tokenFuel > 0){
            address recipient = _isDelayed ? investor : owner;
            withdrawTokens(recipient, tokenFuel);
        }
        if (currentStatus == Status.PENDING_INVESTOR_AGREEMENT) {
            sellData.buyer.transfer(this.balance.sub(msg.value));
        }
        investor.transfer(msg.value);
        Returned(owner, investor, msg.value, _isDelayed);
        return true;
    }

    function supplyFuel(uint256 _amount)
        onlyOwner
        hasStatus(Status.AVAILABLE)
        external
        returns(bool)
    {
        require(token.transferFrom(msg.sender, this, _amount));
        tokenFuel = tokenFuel.add(_amount);
        Supplied(owner, _amount, tokenFuel);
        return true;
    }

    function requireTokenFuel()
        protocolOrInvestor
        hasStatus(Status.INVESTED)
        onlyDelayed
        external
        returns(bool)
    {
        return withdrawTokens(investor, tokenFuel);
    }

}

pragma solidity ^0.4.18;

import './AssetEvents.sol';
import '../token/Token.sol';
import "zeppelin-solidity/contracts/math/SafeMath.sol";

// Defines methods and control modifiers for an investment
contract AssetLibrary is AssetEvents {

    using SafeMath for uint256;

    // Asset owner
    address public owner;
    // Protocol
    address public protocol;
    // Asset currency
    string public currency;
    // Asset fixed value
    uint256 public value;
    //Value bought
    uint256 public boughtValue;
    // period to return the investment
    uint256 public paybackDays;
    // Gross return of investment
    uint256 public grossReturn;
    // Asset buyer
    address public investor;
    // Protocol version
    string public protocolVersion;
    // investment timestamp
    uint public investedAt;

    // asset fuel
    Token public token;
    uint256 public tokenFuel;

    // sell data
    struct Sell {
        uint256 value;
        address buyer;
    }

    Sell public sellData;

    // possible stages of an asset
    enum Status {
        AVAILABLE,
        PENDING_OWNER_AGREEMENT,
        INVESTED,
        FOR_SALE,
        PENDING_INVESTOR_AGREEMENT,
        RETURNED,
        DELAYED_RETURN
    }
    Status public status;

    // Checks the current asset's status
    modifier hasStatus(Status _status) {
        assert(status == _status);
        _;
    }

    // Checks if the owner is the caller
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    // Checks if the investor is the caller
    modifier onlyInvestor() {
        require(msg.sender == investor);
        _;
    }

    modifier protocolOrInvestor() {
        require(msg.sender == investor || msg.sender == protocol);
        _;
    }

    modifier protocolOrOwner() {
        require(msg.sender == owner || msg.sender == protocol);
        _;
    }

    modifier onlyDelayed(){
        require(isDelayed());
        _;
    }

    function isDelayed()
        view
        internal
        returns(bool)
    {
        return now > investedAt + paybackDays * 1 days;
    }

    // Refund and remove the current investor and make the asset available for investments
    function makeAvailable()
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        private
        returns(address, uint256)
    {
        status = Status.AVAILABLE;
        uint256 investedValue = this.balance;
        investor.transfer(investedValue);
        address currentInvestor = investor;
        investor = address(0);
        investedAt = uint(0);
        return (currentInvestor, investedValue);
    }

    function withdrawTokens(address _recipient, uint256 _amount)
        private
        returns(bool)
    {
        assert(tokenFuel >= _amount);
        require(token.transfer(_recipient, _amount));
        TokenWithdrawal(_recipient, _amount);
        tokenFuel = tokenFuel.sub(_amount);
        return true;
    }

    // Add investment interest in this asset and retain the funds within the smart contract
    function invest(address _investor) payable
         hasStatus(Status.AVAILABLE)
         external
         returns(bool)
    {
        status = Status.PENDING_OWNER_AGREEMENT;
        investor = _investor;
        investedAt = now;
        Invested(owner, investor, this.balance);
        return true;
    }

    // Cancel the pending investment
    function cancelInvestment()
        protocolOrInvestor
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        external
        returns(bool)
    {
        var (currentInvestor, investedValue) = makeAvailable();
        Canceled(owner, currentInvestor, investedValue);
        return true;
    }

    // Accept the investor as the asset buyer and withdraw funds
    function withdrawFunds()
        protocolOrOwner
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        external
        returns(bool)
    {
        status = Status.INVESTED;
        uint256 _value = this.balance;
        owner.transfer(_value);
        Withdrawal(owner, investor, _value);
        return true;
    }

    // Refuse the pending investment
    function refuseInvestment()
        protocolOrOwner
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        external
        returns(bool)
    {
        var (currentInvestor, investedValue) = makeAvailable();
        Refused(owner, currentInvestor, investedValue);
        return true;
    }

    function sell(uint256 _sellValue)
        protocolOrInvestor
        hasStatus(Status.INVESTED)
        external
        returns(bool)
    {
        status = Status.FOR_SALE;
        sellData.value = _sellValue;
        ForSale(msg.sender, _sellValue);
        return true;
    }

    function cancelSellOrder()
        protocolOrInvestor
        hasStatus(Status.FOR_SALE)
        external
        returns(bool)
    {
        status = Status.INVESTED;
        sellData.value = uint256(0);
        CanceledSell(investor, value);
        return true;
    }

    function buy(address _buyer) payable
        hasStatus(Status.FOR_SALE)
        external
        returns(bool)
    {
        status = Status.PENDING_INVESTOR_AGREEMENT;
        sellData.buyer = _buyer;
        Invested(investor, _buyer, msg.value);
        return true;
    }

    function cancelSale()
        hasStatus(Status.PENDING_INVESTOR_AGREEMENT)
        external
        returns(bool)
    {
        require(msg.sender == protocol || msg.sender == sellData.buyer);
        status = Status.FOR_SALE;
        address buyer = sellData.buyer;
        uint256 _value = this.balance;
        buyer.transfer(_value);
        sellData.buyer = address(0);
        Canceled(investor, buyer, _value);
        return true;
    }

    // Refunds asset's buyer and became available for sale again
    function refuseSale()
        protocolOrInvestor
        hasStatus(Status.PENDING_INVESTOR_AGREEMENT)
        external
        returns(bool)
    {
        status = Status.FOR_SALE;
        address buyer = sellData.buyer;
        uint256 _value = this.balance;
        buyer.transfer(_value);
        sellData.buyer = address(0);
        Refused(investor, buyer, _value);
        return true;
    }

    // Withdraw funds, clear the sell data and change investor's address
    function acceptSale()
        protocolOrInvestor
        hasStatus(Status.PENDING_INVESTOR_AGREEMENT)
        external
        returns(bool)
    {
        status = Status.INVESTED;
        address currentInvestor = investor;
        uint256 _value = this.balance;
        currentInvestor.transfer(_value);
        investor = sellData.buyer;
        boughtValue = sellData.value;
        sellData.buyer = address(0);
        sellData.value = uint256(0);
        Withdrawal(currentInvestor, investor, _value);
        return true;
    }

    function returnInvestment() payable
        onlyOwner
        external
        returns(bool)
    {
        assert(status == Status.INVESTED || status == Status.FOR_SALE || status == Status.PENDING_INVESTOR_AGREEMENT);
        Status currentStatus = status;
        bool _isDelayed = isDelayed();
        status = _isDelayed ? Status.DELAYED_RETURN : Status.RETURNED;
        if(tokenFuel > 0){
            address recipient = _isDelayed ? investor : owner;
            withdrawTokens(recipient, tokenFuel);
        }
        if (currentStatus == Status.PENDING_INVESTOR_AGREEMENT) {
            sellData.buyer.transfer(this.balance.sub(msg.value));
        }
        investor.transfer(msg.value);
        Returned(owner, investor, msg.value, _isDelayed);
        return true;
    }

    function supplyFuel(uint256 _amount)
        onlyOwner
        hasStatus(Status.AVAILABLE)
        external
        returns(bool)
    {
        require(token.transferFrom(msg.sender, this, _amount));
        tokenFuel = tokenFuel.add(_amount);
        Supplied(owner, _amount, tokenFuel);
        return true;
    }

    function requireTokenFuel()
        protocolOrInvestor
        hasStatus(Status.INVESTED)
        onlyDelayed
        external
        returns(bool)
    {
        return withdrawTokens(investor, tokenFuel);
    }

}


Revert changes to HumonStandardContract, as params are taken over by main contract
 "adjust Pluton parameters"

This partly reverts commit bfa8e47b0ab446dd543520e400485c30b0106b1a.

/*
This Token Contract implements the standard token functionality (https://github.com/ethereum/EIPs/issues/20) as well as the following OPTIONAL extras intended for use by humans.

In other words. This is intended for deployment in something like a Token Factory or Mist wallet, and then used by humans.
Imagine coins, currencies, shares, voting weight, etc.
Machine-based, rapid creation of many tokens would not necessarily need these extra features or will be minted in other manners.

1) Initial Finite Supply (upon creation one specifies how much is minted).
2) In the absence of a token registry: Optional Decimal, Symbol & Name.
3) Optional approveAndCall() functionality to notify a contract if an approval() has occurred.

.*/

import "StandardToken.sol";

contract HumanStandardToken is StandardToken {

    function () {
        //if ether is sent to this address, send it back.
        throw;
    }

    /* Public variables of the token */

    /*
    NOTE:
    The following variables are OPTIONAL vanities. One does not have to include them.
    They allow one to customise the token contract & in no way influences the core functionality.
    Some wallets/interfaces might not even bother to look at this information.
    */
    string public name;                   //fancy name: eg Simon Bucks
    uint8 public decimals;                //How many decimals to show. ie. There could 1000 base units with 3 decimals. Meaning 0.980 SBX = 980 base units. It's like comparing 1 wei to 1 ether.
    string public symbol;                 //An identifier: eg SBX
    string public version = 'H0.1';       //human 0.1 standard. Just an arbitrary versioning scheme.

    function HumanStandardToken(
        uint256 _initialAmount,
        string _tokenName,
        uint8 _decimalUnits,
        string _tokenSymbol
        ) {
        balances[msg.sender] = _initialAmount;               // Give the creator all initial tokens
        totalSupply = _initialAmount;                        // Update total supply
        name = _tokenName;                                   // Set the name for display purposes
        decimals = _decimalUnits;                            // Amount of decimals for display purposes
        symbol = _tokenSymbol;                               // Set the symbol for display purposes
    }

    /* Approves and then calls the receiving contract */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        //call the receiveApproval function on the contract you want to be notified. This crafts the function signature manually so one doesn't have to include a contract in here just for this.
        //receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData)
        _spender.call(bytes4(bytes32(sha3("receiveApproval(address,uint256,address,bytes)"))), msg.sender, _value, this, _extraData);
        Approval(msg.sender, _spender, _value);
        return true;
    }
}

/*
This Token Contract implements the standard token functionality (https://github.com/ethereum/EIPs/issues/20) as well as the following OPTIONAL extras intended for use by humans.

In other words. This is intended for deployment in something like a Token Factory or Mist wallet, and then used by humans.
Imagine coins, currencies, shares, voting weight, etc.
Machine-based, rapid creation of many tokens would not necessarily need these extra features or will be minted in other manners.

1) Initial Finite Supply (upon creation one specifies how much is minted).
2) In the absence of a token registry: Optional Decimal, Symbol & Name.
3) Optional approveAndCall() functionality to notify a contract if an approval() has occurred.

.*/

import "StandardToken.sol";

contract HumanStandardToken is StandardToken {

    function () {
        //if ether is sent to this address, send it back.
        throw;
    }

    /* Public variables of the token */

    /*
    NOTE:
    The following variables are OPTIONAL vanities. One does not have to include them.
    They allow one to customise the token contract & in no way influences the core functionality.
    Some wallets/interfaces might not even bother to look at this information.
    */
    string public name = 'Pluton';                   //fancy name: eg Simon Bucks
    uint8 public decimals = 8;                //How many decimals to show. ie. There could 1000 base units with 3 decimals. Meaning 0.980 SBX = 980 base units. It's like comparing 1 wei to 1 ether.
    string public symbol = 'PLU';                 //An identifier: eg SBX
    string public version = 'H0.1';       //human 0.1 standard. Just an arbitrary versioning scheme.

    function HumanStandardToken(
        uint256 _initialAmount,
        string _tokenName,
        uint8 _decimalUnits,
        string _tokenSymbol
        ) {
        balances[msg.sender] = _initialAmount;               // Give the creator all initial tokens
        totalSupply = _initialAmount;                        // Update total supply
        name = _tokenName;                                   // Set the name for display purposes
        decimals = _decimalUnits;                            // Amount of decimals for display purposes
        symbol = _tokenSymbol;                               // Set the symbol for display purposes
    }

    /* Approves and then calls the receiving contract */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        //call the receiveApproval function on the contract you want to be notified. This crafts the function signature manually so one doesn't have to include a contract in here just for this.
        //receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData)
        _spender.call(bytes4(bytes32(sha3("receiveApproval(address,uint256,address,bytes)"))), msg.sender, _value, this, _extraData);
        Approval(msg.sender, _spender, _value);
        return true;
    }
}


Depoly Tokens on ChainX Blockchain

Depoly Tokens on ChainX Blockchain

pragma solidity ^0.4.8;

import "./Mintable.sol";
import "./../base/Ownable.sol";

contract DummyToken is Mintable, Ownable {
    string public name;
    string public symbol;
    uint public decimals;

    function DummyToken(
        string _name,
        string _symbol,
        uint _decimals,
        uint _totalSupply)
    {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        totalSupply = _totalSupply;
        balances[msg.sender] = _totalSupply;
    }

    function setBalance(address _target, uint _value) onlyOwner {
        uint currBalance = balanceOf(_target);
        if (_value < currBalance) {
            totalSupply = safeSub(totalSupply, safeSub(currBalance, _value));
        } else {
            totalSupply = safeAdd(totalSupply, safeSub(_value, currBalance));
        }
        balances[_target] = _value;
    }
}

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


Update SimpleCrowdsale.sol

Update SimpleCrowdsale.sol

pragma solidity ^0.4.8;

import "./Exchange.sol";
import "./tokens/ChainXToken.sol";
import "./base/Token.sol";
import "./base/Ownable.sol";
import "./base/SafeMath.sol";

contract SimpleCrowdsale is Ownable, SafeMath {

    address public PROXY_ADDRESS;
    address public EXCHANGE_ADDRESS;
    address public PROTOCOL_TOKEN_ADDRESS;
    address public CHX_TOKEN_ADDRESS;

    Exchange exchange;
    Token protocolToken;
    ChainXToken chxToken;

    bool public isInitialized;
    bool public isFinished;
    Order order;

    struct Order {
        address maker;
        address taker;
        address tokenM;
        address tokenT;
        address feeRecipient;
        uint valueM;
        uint valueT;
        uint feeM;
        uint feeT;
        uint expiration;
        uint salt;
        uint8 v;
        bytes32 r;
        bytes32 s;
        bytes32 orderHash;
    }

    modifier saleInitialized() {
        assert(isInitialized);
        _;
    }

    modifier saleNotInitialized() {
        assert(!isInitialized);
        _;
    }

    modifier saleNotFinished() {
        assert(!isFinished);
        _;
    }

    function SimpleCrowdsale(
        address _exchange,
        address _proxy,
        address _protocolToken,
        address _chxToken)
    {
        PROXY_ADDRESS = _proxy;
        EXCHANGE_ADDRESS = _exchange;
        PROTOCOL_TOKEN_ADDRESS = _protocolToken;
        ChainX_TOKEN_ADDRESS = _chxToken;

        exchange = Exchange(_exchange);
        protocolToken = Token(_protocolToken);
        Token = CHXToken(_chxToken);
    }

    /// @dev Allows users to fill stored order by sending ChainX to contract.
    function()
        payable
        saleInitialized
        saleNotFinished
    {
        uint remainingChx = safeSub(order.valueT, exchange.getUnavailableValueT(order.orderHash));
        uint chxToFill = min(msg.value, remainingChx);
        chxToken.deposit.value(chxToFill)();
        assert(exchange.fillOrKill(
            [order.maker, order.taker, order.tokenM, order.tokenT, order.feeRecipient],
            [order.valueM, order.valueT, order.feeM, order.feeT, order.expiration, order.salt],
            chxToFill,
            order.v,
            order.r,
            order.s
        ));
        uint filledProtocolToken = safeDiv(safeMul(order.valueM, chxToFill), order.valueT);
        assert(protocolToken.transfer(msg.sender, filledProtocolToken));
        if (chxToFill < msg.value) {
            assert(msg.sender.send(safeSub(msg.value, chxToFill)));
            isFinished = true;
        }
    }

    /// @dev Stores order and initializes sale.
    /// @param orderAddresses Array of order's maker, taker, tokenM, tokenT, and feeRecipient.
    /// @param orderValues Array of order's valueM, valueT, feeM, feeT, expiration, and salt.
    /// @param v ECDSA signature parameter v.
    /// @param r CDSA signature parameters r.
    /// @param s CDSA signature parameters s.
    function init(
        address[5] orderAddresses,
        uint[6] orderValues,
        uint8 v,
        bytes32 r,
        bytes32 s)
        saleNotInitialized
        onlyOwner
    {
        order = Order({
            maker: orderAddresses[0],
            taker: orderAddresses[1],
            tokenM: orderAddresses[2],
            tokenT: orderAddresses[3],
            feeRecipient: orderAddresses[4],
            valueM: orderValues[0],
            valueT: orderValues[1],
            feeM: orderValues[2],
            feeT: orderValues[3],
            expiration: orderValues[4],
            salt: orderValues[5],
            feeT: orderValues[6]
            v: v,
            r: r,
            s: s,
            orderHash: getOrderHash(orderAddresses, orderValues)
        });

        assert(order.tokenM == PROTOCOL_TOKEN_ADDRESS);
        assert(order.tokenT == CHX_TOKEN_ADDRESS);

        assert(isValidSignature(
            order.maker,
            order.orderHash,
            v,
            r,
            s
        ));

        assert(setTokenAllowance(order.tokenT, order.valueT));
        isInitialized = true;
    }

    function setTokenAllowance(address _token, uint _allowance)
        onlyOwner
        returns (bool success)
    {
        assert(Token(_token).approve(PROXY_ADDRESS, _allowance));
        return true;
    }

    /// @dev Calculates Keccak-256 hash of order with specified parameters.
    /// @param orderAddresses Array of order's maker, taker, tokenM, tokenT, and feeRecipient.
    /// @param orderValues Array of order's valueM, valueT, feeM, feeT, expiration, and salt.
    /// @return Keccak-256 hash of order.
    function getOrderHash(address[5] orderAddresses, uint[6] orderValues)
        constant
        returns (bytes32 orderHash)
    {
        return sha3(
            EXCHANGE_ADDRESS,
            orderAddresses[0],
            orderAddresses[1],
            orderAddresses[2],
            orderAddresses[3],
            orderAddresses[4],
            orderValues[0],
            orderValues[1],
            orderValues[2],
            orderValues[3],
            orderValues[4],
            orderValues[5]
        );
    }

    /// @dev Verifies that an order signature is valid.
    /// @param pubKey Public address of signer.
    /// @param hash Signed Keccak-256 hash.
    /// @param v ECDSA signature parameter v.
    /// @param r ECDSA signature parameters r.
    /// @param s ECDSA signature parameters s.
    /// @return Validity of order signature.
    function isValidSignature(
        address pubKey,
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s)
        constant
        returns (bool isValid)
    {
        return pubKey == ecrecover(
            sha3("\x19CHX Signed Message:\n32", hash),
            v,
            r,
            s
        );
    }

    /// @dev Calculates minimum of two values.
    /// @param a First value.
    /// @param b Second value.
    /// @return Minimum of values.
    function min(uint a, uint b)
        constant
        returns (uint min)
    {
        if (a < b) return a;
        return b;
    }
}

pragma solidity ^0.4.8;

import "./Exchange.sol";
import "./tokens/ChainXToken.sol";
import "./base/Token.sol";
import "./base/Ownable.sol";
import "./base/SafeMath.sol";

contract SimpleCrowdsale is Ownable, SafeMath {

    address public PROXY_ADDRESS;
    address public EXCHANGE_ADDRESS;
    address public PROTOCOL_TOKEN_ADDRESS;
    address public CHX_TOKEN_ADDRESS;

    Exchange exchange;
    Token protocolToken;
    ChainXToken chxToken;

    bool public isInitialized;
    bool public isFinished;
    Order order;

    struct Order {
        address maker;
        address taker;
        address tokenM;
        address tokenT;
        address feeRecipient;
        uint valueM;
        uint valueT;
        uint feeM;
        uint feeT;
        uint expiration;
        uint salt;
        uint8 v;
        bytes32 r;
        bytes32 s;
        bytes32 orderHash;
    }

    modifier saleInitialized() {
        assert(isInitialized);
        _;
    }

    modifier saleNotInitialized() {
        assert(!isInitialized);
        _;
    }

    modifier saleNotFinished() {
        assert(!isFinished);
        _;
    }

    function SimpleCrowdsale(
        address _exchange,
        address _proxy,
        address _protocolToken,
        address _chxToken)
    {
        PROXY_ADDRESS = _proxy;
        EXCHANGE_ADDRESS = _exchange;
        PROTOCOL_TOKEN_ADDRESS = _protocolToken;
        ChainX_TOKEN_ADDRESS = _chxToken;

        exchange = Exchange(_exchange);
        protocolToken = Token(_protocolToken);
        ethToken = EtherToken(_ethToken);
    }

    /// @dev Allows users to fill stored order by sending ChainX to contract.
    function()
        payable
        saleInitialized
        saleNotFinished
    {
        uint remainingEth = safeSub(order.valueT, exchange.getUnavailableValueT(order.orderHash));
        uint ethToFill = min(msg.value, remainingEth);
        ethToken.deposit.value(ethToFill)();
        assert(exchange.fillOrKill(
            [order.maker, order.taker, order.tokenM, order.tokenT, order.feeRecipient],
            [order.valueM, order.valueT, order.feeM, order.feeT, order.expiration, order.salt],
            ethToFill,
            order.v,
            order.r,
            order.s
        ));
        uint filledProtocolToken = safeDiv(safeMul(order.valueM, ethToFill), order.valueT);
        assert(protocolToken.transfer(msg.sender, filledProtocolToken));
        if (ethToFill < msg.value) {
            assert(msg.sender.send(safeSub(msg.value, ethToFill)));
            isFinished = true;
        }
    }

    /// @dev Stores order and initializes sale.
    /// @param orderAddresses Array of order's maker, taker, tokenM, tokenT, and feeRecipient.
    /// @param orderValues Array of order's valueM, valueT, feeM, feeT, expiration, and salt.
    /// @param v ECDSA signature parameter v.
    /// @param r CDSA signature parameters r.
    /// @param s CDSA signature parameters s.
    function init(
        address[5] orderAddresses,
        uint[6] orderValues,
        uint8 v,
        bytes32 r,
        bytes32 s)
        saleNotInitialized
        onlyOwner
    {
        order = Order({
            maker: orderAddresses[0],
            taker: orderAddresses[1],
            tokenM: orderAddresses[2],
            tokenT: orderAddresses[3],
            feeRecipient: orderAddresses[4],
            valueM: orderValues[0],
            valueT: orderValues[1],
            feeM: orderValues[2],
            feeT: orderValues[3],
            expiration: orderValues[4],
            salt: orderValues[5],
            feeT: orderValues[6]
            v: v,
            r: r,
            s: s,
            orderHash: getOrderHash(orderAddresses, orderValues)
        });

        assert(order.tokenM == PROTOCOL_TOKEN_ADDRESS);
        assert(order.tokenT == CHX_TOKEN_ADDRESS);

        assert(isValidSignature(
            order.maker,
            order.orderHash,
            v,
            r,
            s
        ));

        assert(setTokenAllowance(order.tokenT, order.valueT));
        isInitialized = true;
    }

    function setTokenAllowance(address _token, uint _allowance)
        onlyOwner
        returns (bool success)
    {
        assert(Token(_token).approve(PROXY_ADDRESS, _allowance));
        return true;
    }

    /// @dev Calculates Keccak-256 hash of order with specified parameters.
    /// @param orderAddresses Array of order's maker, taker, tokenM, tokenT, and feeRecipient.
    /// @param orderValues Array of order's valueM, valueT, feeM, feeT, expiration, and salt.
    /// @return Keccak-256 hash of order.
    function getOrderHash(address[5] orderAddresses, uint[6] orderValues)
        constant
        returns (bytes32 orderHash)
    {
        return sha3(
            EXCHANGE_ADDRESS,
            orderAddresses[0],
            orderAddresses[1],
            orderAddresses[2],
            orderAddresses[3],
            orderAddresses[4],
            orderValues[0],
            orderValues[1],
            orderValues[2],
            orderValues[3],
            orderValues[4],
            orderValues[5]
        );
    }

    /// @dev Verifies that an order signature is valid.
    /// @param pubKey Public address of signer.
    /// @param hash Signed Keccak-256 hash.
    /// @param v ECDSA signature parameter v.
    /// @param r ECDSA signature parameters r.
    /// @param s ECDSA signature parameters s.
    /// @return Validity of order signature.
    function isValidSignature(
        address pubKey,
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s)
        constant
        returns (bool isValid)
    {
        return pubKey == ecrecover(
            sha3("\x19Ethereum Signed Message:\n32", hash),
            v,
            r,
            s
        );
    }

    /// @dev Calculates minimum of two values.
    /// @param a First value.
    /// @param b Second value.
    /// @return Minimum of values.
    function min(uint a, uint b)
        constant
        returns (uint min)
    {
        if (a < b) return a;
        return b;
    }
}


Include cheating computation service

Include cheating computation service

pragma solidity ^0.4.8;
import "./usingOraclize.sol";
import "./AbstractArbiter.sol";

contract ComputationService is usingOraclize {
  struct Query {
    string URL;
    string JSON;
  }
  mapping(uint => Query) public computation;

  struct Request {
    string input1;
    string input2;
    uint operation;
    uint256 computationId;
    string result;
    address arbiter;
  }

  mapping(uint256 => bytes32) public requestId;
  mapping(bytes32 => Request) public requestOraclize;

  address public arbiter;

  event newOraclizeQuery(string description);
  event newResult(string comp_result);
  event newOraclizeID(bytes32 ID);

  function ComputationService() {
    OAR = OraclizeAddrResolverI(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475);
  }

  function __callback(bytes32 _oraclizeID, string _result) {
    if (msg.sender != oraclize_cbAddress()) throw;
    newResult(_result);

    requestOraclize[_oraclizeID].result = _result;

    // send result to arbiter contract
    AbstractArbiter myArbiter = AbstractArbiter(requestOraclize[_oraclizeID].arbiter);
    myArbiter.receiveResults.gas(50000)(_result, requestOraclize[_oraclizeID].computationId);
  }

  function compute(string _val1, string _val2, uint _operation, uint256 _computationId) payable {
    bytes32 oraclizeID;

    computation[_operation].JSON = strConcat('\n{"val1": ', _val1, ', "val2": ', _val2, '}');

    newOraclizeQuery("Oraclize query was sent, standing by for the answer.");

    oraclizeID = oraclize_query(60, "URL", computation[_operation].URL, computation[_operation].JSON, 350000);

    // store address for specific request
    requestOraclize[oraclizeID].input1 = _val1;
    requestOraclize[oraclizeID].input2 = _val2;
    requestOraclize[oraclizeID].operation = _operation;
    requestOraclize[oraclizeID].computationId = _computationId;
    requestOraclize[oraclizeID].arbiter = msg.sender;

    requestId[_computationId] = oraclizeID;

    newOraclizeID(oraclizeID);
  }

  function provideIndex(string _resultSolver, uint _computationId) {
    // this is for two intergers: always returns 0 and 1 for two two intergers
    Request memory _request = requestOraclize[requestId[_computationId]];

    AbstractArbiter myArbiter = AbstractArbiter(msg.sender);
    myArbiter.receiveIndex(0, 1, _request.operation, _request.computationId, true);
  }

  function registerOperation(uint _operation) payable {
    // operation 0: add two integers
    if (_operation == 0) {
      Query memory twoInt = Query("https://r98ro6hfj5.execute-api.eu-west-1.amazonaws.com/test/int", "");
      computation[0] = twoInt;
    }
    if (_operation == 1) {
      Query memory twoIntWrong = Query("https://r98ro6hfj5.execute-api.eu-west-1.amazonaws.com/test/multiplicationWrong", "");
      computation[1] = twoIntWrong;
    }
  }

  function enableArbiter(address _arbiterAddress) payable {
    arbiter = _arbiterAddress;
    AbstractArbiter myArbiter = AbstractArbiter(_arbiterAddress);
    myArbiter.enableService();
  }

  function disableArbiter(address _arbiterAddress) payable {
    delete arbiter;
    AbstractArbiter myArbiter = AbstractArbiter(_arbiterAddress);
    myArbiter.disableService();
  }

  function getResult(uint _computationId) constant returns (string) {
    return requestOraclize[requestId[_computationId]].result;
  }
}

pragma solidity ^0.4.8;
import "./usingOraclize.sol";
import "./AbstractArbiter.sol";

contract ComputationService is usingOraclize {
  struct Query {
    string URL;
    string JSON;
  }
  mapping(uint => Query) public computation;

  struct Request {
    string input1;
    string input2;
    uint operation;
    uint256 computationId;
    string result;
    address arbiter;
  }

  mapping(uint256 => bytes32) public requestId;
  mapping(bytes32 => Request) public requestOraclize;

  address public arbiter;

  event newOraclizeQuery(string description);
  event newResult(string comp_result);
  event newOraclizeID(bytes32 ID);

  function ComputationService() {
    OAR = OraclizeAddrResolverI(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475);
  }

  function __callback(bytes32 _oraclizeID, string _result) {
    if (msg.sender != oraclize_cbAddress()) throw;
    newResult(_result);

    requestOraclize[_oraclizeID].result = _result;

    // send result to arbiter contract
    AbstractArbiter myArbiter = AbstractArbiter(requestOraclize[_oraclizeID].arbiter);
    myArbiter.receiveResults.gas(50000)(_result, requestOraclize[_oraclizeID].computationId);
  }

  function compute(string _val1, string _val2, uint _operation, uint256 _computationId) payable {
    bytes32 oraclizeID;

    computation[_operation].JSON = strConcat('\n{"val1": ', _val1, ', "val2": ', _val2, '}');

    newOraclizeQuery("Oraclize query was sent, standing by for the answer.");

    oraclizeID = oraclize_query(60, "URL", computation[_operation].URL, computation[_operation].JSON, 350000);

    // store address for specific request
    requestOraclize[oraclizeID].input1 = _val1;
    requestOraclize[oraclizeID].input2 = _val2;
    requestOraclize[oraclizeID].operation = _operation;
    requestOraclize[oraclizeID].computationId = _computationId;
    requestOraclize[oraclizeID].arbiter = msg.sender;

    requestId[_computationId] = oraclizeID;

    newOraclizeID(oraclizeID);
  }

  function provideIndex(string _resultSolver, uint _computationId) {
    // this is for two intergers: always returns 0 and 1 for two two intergers
    Request memory _request = requestOraclize[requestId[_computationId]];

    AbstractArbiter myArbiter = AbstractArbiter(msg.sender);
    myArbiter.receiveIndex(0, 1, _request.operation, _request.computationId, true);
  }

  function registerOperation(uint _operation) payable {
    // operation 0: add two integers
    if (_operation == 0) {
      Query memory twoInt = Query("https://r98ro6hfj5.execute-api.eu-west-1.amazonaws.com/test/int", "");
      computation[0] = twoInt;
    }
  }

  function enableArbiter(address _arbiterAddress) payable {
    arbiter = _arbiterAddress;
    AbstractArbiter myArbiter = AbstractArbiter(_arbiterAddress);
    myArbiter.enableService();
  }

  function disableArbiter(address _arbiterAddress) payable {
    delete arbiter;
    AbstractArbiter myArbiter = AbstractArbiter(_arbiterAddress);
    myArbiter.disableService();
  }

  function getResult(uint _computationId) constant returns (string) {
    return requestOraclize[requestId[_computationId]].result;
  }
}


Create CrowdsaleTokenBounty

Create CrowdsaleTokenBounty

pragma solidity ^0.4.0;
import './PullPayment.sol';
import './token/CrowdsaleToken.sol';

/*
 * Bounty
 * This bounty will pay out if you can cause a CrowdsaleToken's balance
 * to be lower than its totalSupply, which would mean that it doesn't
 * have sufficient ether for everyone to withdraw.
 */
contract Bounty is PullPayment {

  bool public claimed;
  mapping(address => address) public researchers;

  function() {
    if (claimed) throw;
  }

  function createTarget() returns(CrowdsaleToken) {
    CrowdsaleToken target = new CrowdsaleToken();
    researchers[target] = msg.sender;
    return target;
  }

  function claim(CrowdsaleToken target) {
    address researcher = researchers[target];
    if (researcher == 0) throw;
    // Check CrowdsaleToken contract invariants
    // Customize this to the specifics of your contract
    if (target.totalSupply() == target.balance) {
      throw;
    }
    asyncSend(researcher, this.balance);
    claimed = true;
  }

}

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