contract TokenTrader is owned {

    address public asset;       // address of token
    uint256 public sellPrice;   // contract sells lots of tokens at this price
    uint256 public units;       // lot size (token-wei)

    bool public sellsTokens;    // is contract selling

    event ActivatedEvent(bool sells);
    event UpdateEvent();

    function TokenTrader (
        address _asset, 
        uint256 _sellPrice, 
        uint256 _units,
        bool    _sellsTokens
        )
    {
          asset         = _asset; 
          sellPrice    = _sellPrice;
          units         = _units; 
          sellsTokens   = _sellsTokens;

          ActivatedEvent(sellsTokens);
    }

    // modify trading behavior
    function activate (
        bool    _sellsTokens
        ) onlyOwner
    {
          sellsTokens   = _sellsTokens;

          ActivatedEvent(sellsTokens);
    }

    // allow owner to remove trade token
    function withdrawAsset(uint256 _value) onlyOwner returns (bool ok)
    {
        return ERC20(asset).transfer(owner,_value);
        UpdateEvent();
    }

    // allow owner to remove arbitrary tokens
    // included just in case contract receives wrong token
    function withdrawToken(address _token, uint256 _value) onlyOwner returns (bool ok)
    {
        return ERC20(_token).transfer(owner,_value);
        UpdateEvent();
    }

    // allow owner to remove ETH
    function withdraw(uint256 _value) onlyOwner returns (bool ok)
    {
        if(this.balance >= _value) {
            return owner.send(_value);
        }
        UpdateEvent();
    }

    //user buys token with ETH
    function buy() payable {
        if(sellsTokens || msg.sender == owner) 
        {
            uint order   = msg.value / sellPrice; 
            uint can_sell = ERC20(asset).balanceOf(address(this)) / units;

            if(order > can_sell)
            {
                uint256 change = msg.value - (can_sell * sellPrice);
                order = can_sell;
                if(!msg.sender.send(change)) throw;
            }

            if(order > 0) {
                if(!ERC20(asset).transfer(msg.sender,order * units)) throw;
            }
            UpdateEvent();
        }
        else if(!msg.sender.send(msg.value)) throw;  // return user funds if the contract is not selling
    }

    // sending ETH to contract sells GNT to user
    function () payable {
        buy();
    }
}
// contract can sell tokens for ETH
// prices are in amount of wei per batch of token units
function withdrawToken(address _token, uint256 _value) onlyOwner returns (bool ok)
{
    return ERC20(_token).transfer(owner,_value);
    UpdateEvent();
}

// allow owner to remove arbitrary tokens
// included just in case contract receives wrong token